【问题标题】:Angular custom validation directive. Get errors from view modelAngular 自定义验证指令。从视图模型中获取错误
【发布时间】:2016-08-16 00:01:13
【问题描述】:

我有以下 (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" 定义了哪个变量包含要在每个 validator 指令中使用的错误...

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

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
  } 

}

问题

验证器的链接函数指令中,我需要跟踪validation="vm.errors"传递的变量的变化,这样我就可以在每个验证器中检查是否发生错误并采取措施。

但是console.log(errors) 好像没有效果...

我该如何解决这个问题?

【问题讨论】:

  • 你测试过你的 JSFiddle 吗?它工作不正常
  • 刚刚更新:jsfiddle.net/f30bj43t/5。顺便说一句,前一个提琴手的问题是,将验证器从表单移动到我有控制器的外部 div 给了我这个错误......这也是我想解决的问题。

标签: angularjs


【解决方案1】:

您可以使用 $watch$broadcast$on
我更喜欢使用$on,因为观看一个变量比听一个事件消耗更多,我会说,对于您的情况,最好使用 $broadcast 和 $on,因为您不是在观看范围变量,而是来自控制器的变量。

如果你想了解更多关于 $on 和 $watch 的信息,这里有一个建议:Angular JS $watch vs $on

这是您的 JSFiddle 修改后的内容。

【讨论】:

  • Gabriel,不幸的是我不能使用你的例子,因为我需要在指令方面完成所有工作......所以它必须是一个指令来观察在validation =“vm”中定义的变量中发生了什么.错误”。所以我认为做到这一点的方法是使用手表。我的想法是这样的:jsfiddle.net/q0dy20nv/1 ...你能帮我完成这项工作吗...这是我最大的问题。
  • 很抱歉花了这么长时间才回答,我一直很忙。现在我刚刚更新了 JSFiddle,请检查并判断它是否满足您的需求。 =)
  • 我按照您的示例进行操作,但发生了一些奇怪的事情。如果变量不是数组并且我观察它而不是观察它的长度,那么手表只会触发一次......你知道为什么吗?我只是用那个改变来分叉你的例子:jsfiddle.net/qb8o006h/2
  • 这是一个调整 jsfiddle.net/qb8o006h/4 。我猜问题是因为变量中的更改不会反映在控制器中,因为它是一个数字,而不是 javascript 对象,并且每次更新它时,引用都会丢失。我让控制器监视变量,这就成功了。如果还有其他原因,我真的不知道。
【解决方案2】:

这里有一个工作的 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 是添加到控制器范围内的变量,并且此范围内的所有指令默认都将继承它(有办法避免这种情况)。

无论如何,您似乎创建了太多指令。在你的情况下,对我来说,将所有东西都放在控制器中就足够了。

干杯

哈维尔

【讨论】:

  • 对不起,但这对我不起作用……我已经这样做了。问题出在一个页面上,我可能有多个带有 vm1、vm2 等的控制器……这就是我使用验证 =“vm.errors”的原因。指出错误在哪里。这是我的主要问题......我需要能够在validation="vm1.errors" 中指出要观察的变量是什么。看看为什么你的例子不起作用:jsfiddle.net/cLqa1gqd/1.
猜你喜欢
  • 1970-01-01
  • 2012-11-20
  • 2016-03-17
  • 1970-01-01
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2017-05-26
相关资源
最近更新 更多