角度自定义验证指令。从视图模型中获取错误

时间:2016-04-22 11:17:29

标签: angularjs

我有以下(https://jsfiddle.net/f30bj43t/5/)HTML:

<div ng-controller="DataController as vm">
  <div ng-repeat="name in vm.users track by $index">{{name}}</div>
  <form name="form" validation="vm.errors">
    <input validator ng-model="vm.name" name="vm.name" placeholder="name" type="text" />
    <a href="#" ng-click="vm.add(vm.name)">Add</a>
  </form>
</div>

此表单将名称添加到列表中,控制器为:

app.controller("DataController", DataController);

function DataController() {
  var vm = this;
  vm.name = "Mary";
  vm.users = ["Alice", "Peter"];
  vm.errors = [];
  vm.add = function(name) {  
    if (name == "Mary") {
      var error = { property: "name", message: "name cannot be Mary"};
      if (vm.errors.length == 0) 
        vm.errors.push(error);        
      } else {
        vm.users.push(name);      
        vm.errors = [];
      }      
    }
}

在表单上,​​我添加了 validation="vm.errors" ,用于定义哪个变量包含要在每个验证器指令中使用的错误...

然后在每个验证器指令中,我将使用该变量来选择正确的错误并显示它......

app.directive("validation", validation);

function validation() {

  var validation = {
    controller: ["$scope", controller],
    replace: false,
    restrict: "A",
    scope: {
      validation: "="
    }
  };

  return validation;

  function controller($scope) { 
    this.getErrors = function () {
      return $scope.validation;
    }    
  } 

}  

app.directive("validator", validator);

function validator() {

  var validator = {
    link: link,
    replace: false,
    require: "^validation",
    restrict: "A"
  };

  return validator;

  function link(scope, element, attributes, controller) {    
    var errors = controller.getErrors();
    console.log(errors);    
    // do something with errors
  } 

}

问题

验证器指令的链接功能中,我需要跟踪验证传递的变量的变化=&#34; vm.errors&#34;所以我可以在每个验证器中检查是否发生错误并采取措施。

但是console.log(错误)似乎没有效果......

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

您可以使用$watch$broadcast$on执行此操作 我更喜欢使用$on,因为观看变量比听取一个事件消耗的更多,而且我说你的情况下使用$ broadcast和$ on更好,因为你&# 39;不是观察范围变量,而是来自控制器的变量。

如果您想了解有关$ on和$ watch的更多信息,请参阅以下建议:Angular JS $watch vs $on

这是你的JSFiddle的修改。

答案 1 :(得分:1)

这里有一个有效的jsfiddle:https://jsfiddle.net/f30bj43t/8/

每次更改时,我都会将vm.errors变量记录到控制台中:

function link(scope, element, attributes, controller) {   
    scope.$watch('vm.errors.length', function () {
        if(scope.vm.errors){
            console.log(scope.vm.errors);
        }   
  });
} 

由于范围继承,这是可能的。在您的情况下,vm是添加到控制器范围的变量,并且此范围内的所有指令将默认继承它(有办法避免这种情况)。

无论如何,你似乎创造了太多的指令。在你的情况下,对我来说就足够了控制器中的一切。

干杯

哈维尔