angularjs – 一次一封電子郵件表單驗證

我正在嘗試為電子郵件欄位實現表單驗證.驗證應該做到以下:

>檢查是否已通過必需屬性輸入電子郵件,如果未輸入電子郵件則顯示訊息

>檢查電子郵件是否具有有效格式(似乎是在沒有指定屬性的情況下自動完成)並在格式錯誤時顯示訊息

>檢查電子郵件在$http.get電話上是否唯一,並在發現電子郵件時顯示一條訊息,因此無法使用

我希望顯示第一條訊息,如果該欄位為空,則在電子郵件無效且第三條訊息出現時顯示第二條訊息,如果找到電子郵件地址,因此一次不唯一.

如果我只嘗試“required”屬性,這很有效,但是一旦我添加了我的email-available指令屬性,它就不再檢查電子郵件的格式,並且email-available指令與required屬性一起執行.兩個訊息都會彈出,但我只希望使用者一次看到一條訊息.

我正在使用angularjs 1.1.3.

誰能告訴我,我可能做錯了什麼?

HTML

<div id="user_mod" class="mod_form" ng-show="userModScreenIsVisible">
<form name="mod_user" novalidate>
    <input type="email" name="email" ng-model="user.email" placeholder="E-Mail" required email-available/>
    <div class="user-help" ng-show="mod_user.email.$dirty && mod_user.email.$invalid">Invalid:
        <span ng-show="mod_user.email.$error.required">Please enter your email.</span>
        <span ng-show="mod_user.email.$error.email">This is not a valid email.</span>
        <span ng-show="mod_user.email.$error.emailAvailable">This email address is already taken.</span>
    </div>
</form>

指示

directive('emailAvailable', function($http) { // available
    return {
        require: 'ngModel',
        link: function(scope, elem, attr, ctrl) {
            ctrl.$parsers.unshift(function(viewValue) {
                ctrl.$setValidity('emailAvailable', false);
                if(viewValue !== "" && typeof viewValue !== "undefined") {
                    console.log("variable is defined");

                    $http.get('/api/user/email/' + viewValue + '/available')
                        .success(function(data, status, headers, config) {
                            console.log(status);
                            ctrl.$setValidity('emailAvailable', true);
                            return viewValue;
                        })
                        .error(function(data, status, headers, config) {
                            console.log("error");
                            ctrl.$setValidity('emailAvailable', false);
                            return undefined;
                        });
                } else {
                    console.log("variable is undefined");
                    ctrl.setValidity('emailAvailable', false);
                    return undefined;
                }
            });
        }
    };
});

我看到你已經解決了自己的問題,但我想我可以在這裡給你一些提示/建議(我希望):

1)你需要做的就是確保你的驗證器在內建的角度驗證器推入()後執行到ctrl.$parsers,而不是unshift()它.

2)由於先前執行的驗證程序顯示它無效(即如果欄位已經失效,如果您不想進行Ajax呼叫),則要使驗證程序無法執行.您只需要在驗證器內的if語句中檢查ctrl.$invalid.

3)在開始ajax呼叫之前以及收到之後,您需要單獨呼叫$setValidity()來使表單無效.這樣,在AJAX返回之前,您的表單無效,並說明它是否有效.

4)這可能很小,但除非你新增一個ctrl.$formatter,最初分配給$scope中物件的值在寫入螢幕之前不會被驗證.如果您的表單通過路由,ng-repeat或ng-include動態新增到螢幕,並且預先填充了資料,則可能會出現問題.通常,所有驗證器都應具有$parser元件(view – > model)和$formatter元件(model – > view).

5)謹慎一點.如果模型無效,大多數驗證器都將完全刪除模型中的值.因為你正在進行非同步呼叫,所以你必須立即在解析器函式中返回viewValue.如果欄位無效,解析器函式通常會返回undefined,從而防止無效資料出現在模型中.

6)由於驗證器具有在$error物件中維護的狀態,因此在最初命中此非同步驗證器時,您需要清除它.見下文.

7)旁註:在你的回答中,我注意到你在ajax響應處理程序中返回值…這對你沒有任何作用.因為呼叫是非同步的,所以你總是從該解析器返回undefined.它會更新你的型號嗎?如果確實如此,我會感到驚訝.

以下是我如何更改您的原始指令以使其按您可能的方式工作:

app.directive('emailAvailable', function($http, $timeout) { // available
    return {
        require: 'ngModel',
        link: function(scope, elem, attr, ctrl) {
          console.log(ctrl);
            // push the validator on so it runs last.
            ctrl.$parsers.push(function(viewValue) {
                // set it to true here, otherwise it will not 
                // clear out when previous validators fail.
                ctrl.$setValidity('emailAvailable', true);
                if(ctrl.$valid) {
                  // set it to false here, because if we need to check 
                  // the validity of the email, it's invalid until the 
                  // AJAX responds.
                  ctrl.$setValidity('checkingEmail', false);

                  // now do your thing, chicken wing.
                  if(viewValue !== "" && typeof viewValue !== "undefined") {
                      $http.get('/api/user/email/' + viewValue + '/available')
                          .success(function(data, status, headers, config) {
                              ctrl.$setValidity('emailAvailable', true);
                              ctrl.$setValidity('checkingEmail', true);
                          })
                          .error(function(data, status, headers, config) {
                              ctrl.$setValidity('emailAvailable', false);
                              ctrl.$setValidity('checkingEmail', true);
                          });
                  } else {
                      ctrl.$setValidity('emailAvailable', false);
                      ctrl.$setValidity('checkingEmail', true);
                  }
                }
                return viewValue;
            });

        }
    };
});

And… of course, here is a plunker demonstrating it all

翻譯自:https://stackoverflow.com/questions/15592117/email-form-validation-one-at-a-time