是否可以在指令中以编程方式链接事件处理程序?

时间:2015-02-11 02:57:44

标签: javascript angularjs

当我在同一个表单中单击一个按钮时,我一直试图想出一种触发输入元素验证例程的方法。我一直在寻找几种不同的方法。似乎最不复杂的是创建一个指令来修改输入按钮以在目标表单元素上触发$ validate方法。我已经设置了这个没有太多麻烦,但我已经被阻止如何修改ngClick事件处理程序,以便它触发$ validate,同时保留原始HTML定义的ngClick完整。

我试图使用指令模板函数来提取原始ngClick方法并将其链接到指令中定义的新ngClick函数。这开始很快变成一团糟,我担心它会有多么脆弱。

有没有办法拦截指令中的ngClick处理程序并且原始功能仍然完整?

或者,我很乐意接受有关如何在单击按钮时触发输入字段上的验证例程的建议,而控制器层的参与最少。

1 个答案:

答案 0 :(得分:1)

这是XY-question的经典示例(如果不是双XY问题)。

您不需要链接事件处理程序" (无论你的意思是什么)。我认为,您不需要手动触发验证,因为您正在验证外部数据。

Angular中的验证只是运行 - 除了通过更改数据之外,它并不意味着被触发。

要添加自己的自定义验证器,您需要创建一个指令(它似乎就是这样)。在该指令中,您可能需要指定要验证的内容,例如要检查重复项的字符串数组。

为简单起见,我们要说明您要对ViewModel中的其他值进行验证。假设,这将如何使用:

<input ng-model="bar">
<form name="form1">
  <input ng-model="foo" not-equal-to="bar">
</form>
<span ng-show="form1.$error.notEqualTo">error: foo is equal to bar</span>

因此,您需要创建一个指令notEqualTo,为ngModel.$validators管道添加验证器。该指令还需要$watch更改bar并重新设置有效性:

app.directive("notEqualTo", function(){
  return {
    require: "ngModel",
    scope: {
      notEqualTo: "="
    },
    link: function(scope, element, attrs, ngModel){

      // register "notEqualTo" validator
      ngModel.$validators.notEqualTo = function(modelValue){
        return validate(modelValue, scope.notEqualTo);
      };

      // rerun validation on changes to scope.notEqualTo
      scope.$watch("notEqualTo", function(){
        ngModel.$setValidity("notEqualTo", 
                                validate(ngModel.$modelValue, scope.notEqualTo));
      });

      function validate(one, other){
        return one !== other;
      }
    }
  };
});

plunker