2013-01-09 43 views
2

我知道我在問一個問題,它有一個非常簡單的答案(我對angular很陌生,在這裏需要很多勇氣)。我有一個顯示這樣的時間的指令:當偵聽器是Date()函數時,角度守望者不起作用

Application.Directives 
.directive('theClock', function(){ 
    return { 
     retrict: 'EA', 
     templateUrl: 'partials/partial.clock.html', 
     link: function(scope, elem, attrs) { 

      scope.dTime = Date(); 
      scope.$watch(function(scp){ return Date(); }, function(newVal){ 

        scope.dTime = newVal; 
       } 
      ); 
     } 
    }; 
}); 

我預計的時間將更新每個$消化週期,但事實並非如此。我知道使用setInterval$timeout是另一種方式來做到這一點,但我並不真的想要一個時鐘,我想了解爲什麼更新不會發生。順便說一句我沒有打電話$apply()檢查後$$phase - 沒有幫助

謝謝。

+0

奇怪...只是將您的代碼導入到[Plnkr](http://plnkr.co/edit/bMVqWBQ9qBVl90zhTdgZ),日期已更新爲每個摘要(只需更改要檢查的輸入值 - 更新每個按鍵日期) –

+0

@ValentynShybanov - 是的,它會更新如果你改變一個輸入值,但不是定期調用$ digest,特別是因爲我設置了一個觀察者?此外,即使對$ apply()的調用似乎也沒有幫助。 –

+0

我剛要問一個同樣的問題。由於我創建了plunk,所以我會把它放在評論中:http://plnkr.co/edit/ehud1hFP6opyrnNWvbjA?p=preview *(所以當這個問題在幾個月後再次出現時我會有一個參考點)* –

回答

5

$ watch函數默認情況下通過引用比較對象,這對字符串/數字值更快更好,但對於複雜對象(如Date)不起作用 - 日期可能會更改,但它始終是相同的Date對象,所以參考不會改變。

這是爲了避免在巨大的陣列上進行嚴重的相等測試。

現在,雖然這可能工作(注意設置爲true $表函數的第三個參數):

scope.dTime = new Date(); 
scope.$watch(function(scp){ return new Date(); }, function(newVal){ 

    scope.dTime = newVal; 
    }, true 
); 

它可能會每次都輪詢$手錶功能(每意味着觸發更改事件單個應用週期)

如果您希望每秒觸發一次,則返回Date()中的秒數,返回Math.floor(new Date()。valueOf()/ 1000)之類的值。然後根據需要設置dTime。

更新

雖然角度的檢查將與return Date()工作,這個問題是由於角的髒檢查系統 - 它只會檢查$表函數時的變化觸發了模型(指定義的模型在$範圍內)。

這個Plnkr,來自Valentyn Shybanov's,可以作爲一個例子 - 時鐘函數觸發模型的變化,並且該變化觸發$ watch函數。

還有,通知this version,它使用window.setTimeout。它只能使用$ apply方法來通知angularJS發生了更改。

+0

你大概是正確的,$ watch通過引用來比較,這就是爲什麼我將Date()放在我自己的函數中的原因。因爲沒有「new」的Date()只返回一個字符串(每次都有一個不同的字符串),所以我希望我的回調函數更新應該調用的作用域。此外,您的代碼沒有更新顯示的時間。不管怎麼說,還是要謝謝你。 –

+0

它確實 - 只是檢查@Valentyn Shybanov的Plnkr。問題是角度的髒檢查過程。它檢查各個$範圍中的註冊值,並且僅在某些更改時才起作用。 –

+1

是的,只有,不,它不。如果你想要一個外部事件對你的angularJS應用產生影響,你需要告訴它發生了什麼(使用$ apply方法) –

2

「我想知道爲什麼更新不會發生。」

我覺得這幅畫(從Conceptual Overview page)最能解釋它:不檢查

Angular event loop

的$觀察名單,除非$適用()被調用。 $ apply是我們輸入「$ digest循環」的方式。很多(所有?)角內置指令自動調用$應用(所以我們不必)。例如,作爲@Tiago已經提到的,不斷變化的(內部角)綁定$ scope屬性將導致$申請被調用。我們還可以顯式調用$申請自己(例如,從我們定義了一個第三方庫的回調函數內 - 如果我們不調用$適用於此處,我們不會進入$消化循環)。底線:除非我們進入藍框(「Angular execution context」),否則$ watch列表不會被檢查 - 所以髒檢查不會被執行。

相關問題