簡體   English   中英

Angular:對表單元素的指令訪問

[英]Angular: directive access to form element

我有一個包含輸入的表單標簽:

<label data-live-email-check="http://www.example-service-uri.com/">
    <span class="embedded-label">Email</span>
    <input ng-model="formData.email"
           type="email"
           name="email"
           placeholder="Email"
           required/>
    <span class="message" ng-show="emailValidationMessage">{{emailValidationMessage}}</span>
</label>

我想創建一個指令,該指令采用data-live-email-check屬性提供的URL並將電子郵件發送到該URL,以驗證該電子郵件是否已經存在。

angular.module("App").directive("liveEmailCheck", [function () {
    return {
        restrict: "A",
        scope: {
            ngModel: "="
        },
        link: function (scope, element, attrs) {
            scope.$watch(
                function(){
                    return scope.ngModel
                },
                function(newVal){
                    console.log(newVal);
                }
            );
        }
    }
}]);

我只想查看輸入中的模型,並在更新時發出請求。 由於指令是在標簽元素上定義的,因此ngModel未正確綁定。 我究竟做錯了什么? 我的手表表達式沒有記錄任何內容,因為它從不觸發。

我知道我可以手動獲取輸入,但是好像我要打破我覺得被“束縛”的“角度模式”。 令人沮喪的是,在Angular中似乎有太多的方法可以完成所有工作,我無法確定自己是否正確地解決了問題。

- 編輯 -

為了提供我個人會采取的解決方案(出於對“更好”方法的無知),將是以下內容:

angular.module("App").directive("liveEmailCheck", [function () {
    return {
        restrict: "A",
        require: ["^form"],
        link: function (scope, element, attrs, ctrl) {
            var formCtrl = ctrl[0];
            scope.formEl = formCtrl[element.find("input").attr("name")];


            scope.$watch(function(){return scope.formEl.$valid},  
                function(newVal){
                    console.log(newVal);
                });
        }
    }
}]);

這種方法有效,但是我感覺它“打破了棱角規則”。

自定義驗證的編寫方式如下:

'use strict';

angular.module('App')
  .directive('liveEmailCheck', function (){

    return {
      require: 'ngModel',
      link: function (scope, elem, attr, ngModel){
        ngModel.$validators.liveEmailCheck= function (value){
         //Your logic here or in a factory
        };
      }
    };
  });

然后在您的HTML上

<input type="email" live-email-check="liveEmailCheck>

基本上,您將自己的驗證添加到angular的內置驗證集中。

您需要的是ng模型asyncValidator 這是這種指令的簡單實現。

angular.module("App").directive('asyncEmailValidator', function ($http) {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {
      var emailValidationUrl = attrs.asyncEmailValidator;
      ngModel.$asyncValidators.emailValidator = function (modelValue, viewValue) {
        var value = modelValue || viewValue;
        // NOTE: don't forget to correctly add the value to the url
        return $http(emailValidationUrl + value).then(function (validationResponse) {
          // NOTE: return rejected promise if validation failed else true
        });

      };
    }
  };
});

在您的情況下如何使用它:

<label>
    <span class="embedded-label">Email</span>
    <input ng-model="formData.email"
           async-email-validator="http://www.example-service-uri.com/"
           type="email"
           name="email"
           placeholder="Email"
           required/>
    <span class="message" ng-show="<FormNameHere>.email.$error.emailValidator">
        {{emailValidationMessage}}
    </span>
</label>

這是正確的解決方案,因為它是通過角度ng模型驗證來實現的,而角度ng模型驗證也考慮了模型的有效性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM