2015-04-17 44 views
7

我是新来的角的js发射只有一次,所以请有人帮我out.I有我的模板在这里:

<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”仅在我第一次输入任何值到文本框时被触发一次。提前致谢。

+1

您可能想要观察模型的属性,而不仅仅是对象本身:'scope。$ watch(attrs.ngModel,{...},true);' – Blackhole

+0

它适用于我。什么是第三个参数“真正的“在做。以前没有”真实“它只发射一次。 – Nitya

+0

第三个参数是观察“深”还是不。例如检查它的同一对象或检查对象是否具有相同的键/值 – dogmatic69

回答

-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); 
     }); 
     } 
    } 
    }); 

编辑:最快的解决办法将是黑洞跟随评论,并通过添加true更新您的手表了深刻的手表。这是因为您正在观看signup属性,但模型值username是注册的属性。深度手表将用于观看物业。

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

+1

OP正在观察'attrs.ngModel'的内容,即'signup',它是一个通过继承变量的范围变量。 – Blackhole

+0

不错,我一直试图在链接函数中使用范围与attrs的区别来试图避免与继承范围的混淆。我会更新我的答案,但迈克尔提供了一个很好的解决方案。谢谢。 – Asta

+0

谢谢Asta.I给watcher添加了一个“true”。它现在正在工作 – Nitya

3

当您使用ngModelController,观看模型上的变化的标准方法是通过创建一个formatter

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

请记住,当模型直接改变格式化只触发。如果改变来自UI(即用户改变某些内容),则代替触发解析器。所以,你可能需要做的还有:

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

​​

我建议你阅读ngModelController文档,以便您了解这些管道究竟是如何工作的。

但是,如果你想要做的一切都得到通知时模型的变化(你不想要或需要既不格式也不解析任何东西),那么你可以做一些简单的:

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

Working Plunker

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

UPDATE

值得一提的是,ngModelController已经可以说是一个缺点:它不与“参考”类型(例如数组,对象)很好地工作。更多细节可以在here找到。

+0

谢谢Michael.But我想知道一件事。当我向观察者添加第三个参数为“真正”时,它开始观察模型。但之前为什么它只发射一次?下面的代码适用于我 范围。$ watch('model',function – Nitya

+0

@Nitya第三个参数告诉Angular使用'angular.equals'来比较值(即它做了深入的比较)。因此,如果您需要监视某个对象并在其某个属性发生变化时收到通知,则需要设置该参数(以换取某些性能)。这是'ngModelController'的一个缺点:它不会进行那种比较,因此可以更好地处理“值类型”。 –

+0

@Nitya关于手表只发射一次,这是预期的。每个手表至少运行一次(如果被监视的属性没有值,则使用未定义的参数),如您在[this plunker](http://plnkr.co/edit/2qWMhOkTSH403i6k0ti0?p=preview)中看到的那样。 –