$ watch只在内部指令中触发一次

时间:2015-04-17 19:06:12

标签: angularjs

我是棱角分明的新手,所以请一些人帮帮我。我的模板在这里:

<form ng-model="signup" form-valid>
    <input type="text" name="username" ng-model="signup.username">{{signup}}
</form>

我的指示是这样的:

app.directive("formValid",function(){

 return {
    restrict:"A",
    require:"ngModel",
    link:function(scope,element,attrs){
          scope.$watch(attrs.ngModel,function(newValue){
              if(newValue){
                 console.log(newValue);
              }
          });
       }
   }});

当我在文本框中输入一些值时,模型正在改变,因此“$ watch”应该被触发。但是在这里“$ watch”只在我第一次在文本框中输入任何值时被触发一次谢谢你。

2 个答案:

答案 0 :(得分:3)

当您使用ngModelController时,观看模型更改的标准方法是创建formatter

link: function(scope, element, attrs, ngModelCtrl) {
    ngModelCtrl.$formatters.push(function(value) {
        // Do something with value
        return value;
    });
}

请注意, formatters 仅在直接更改模型时触发。如果更改来自UI(即用户更改某些内容),则会触发解析器。所以你可能也需要这样做:

ngModelCtrl.$parsers.push(function(value) {
    // Do something with value
    return value;
});

Working Plunker

我建议您阅读ngModelController文档,以便准确了解这些管道的工作原理。

但是,如果您想要做的就是在模型发生变化时得到通知(您不想或不需要格式化或解析任何内容),那么您可以做一些更简单的事情:

scope: { model: '=ngModel' },
link: function(scope) {
    scope.$watch('model', function(value) {
        // Do something with value
    });
}

Working Plunker

但是考虑到你的指令名formValid,我认为使用ngModelController是正确的方法。

<强>更新

值得一提的是,ngModelController可能存在一个缺点:它并没有很好地与&#34;引用&#34;类型(例如数组,对象)。有关详细信息,请访问here

答案 1 :(得分:-1)

一种解决方案是使用类似下面示例中的ngModel。

app.directive("formValid",function(){
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, element, attrs, ngModel) {
      scope.$watch(function () {
          return ngModel.$modelValue;
        }, function(newValue) {
          console.log(newValue);
        });
      }
    }
  });

编辑:最快的解决方案是按照 Blackhole 的评论,并通过添加true来更新您的手表。这是因为您正在查看signup属性,但模型值username是注册属性。深表将用于观看物业。

直接使用ngModel,而不是attrs,或使用格式化程序或解析器(在我看来,Michaels答案中详述的是更好的解决方案)。