2015-04-17 37 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)中看到的那樣。 –