2014-07-09 73 views
1

我試圖在服務函數的返回值更改時更新scope。從閱讀,這聽起來像我應該使用$watch,但以下角度docs在我的應用程序創建一個無限$digest循環,這裏的控制器:

.controller('navCtrl', function(CookieHandler, $scope){ 
    // this works, but doesn't update when CookieHandler.get() changes 
    // $scope.user = CookieHandler.get(); 

    $scope.$watch(
    function() {return CookieHandler.get()}, 
    function(newValue, oldValue) { 
     if(newValue !== oldValue) { 
     $scope.user = newValue 
     } 
    } 
) 
    //etc 

從錯誤消息,還有一些關於使用$觀看函數返回一個數組,但CookieHandler.get()返回一個對象?

我看了看周圍的一些更讀,我應該使用的$apply代替$watch這裏,因爲它更容易測試,所以我想這:

.controller('navCtrl', function(CookieHandler, $scope){ 
    // this works, but doesn't update when CookieHandler.get() changes 
    // $scope.user = CookieHandler.get(); 

    $scope.$apply(function(scope){ 
    scope.user = CookieHandler.get(); 
    }) 
}) 

但是,這將引發對消化週期的誤差已經在運行。有沒有辦法解決我的$watch停止無限循環? CookieHandler.get只是檢查值$cookieStore

+0

當您從角度已知事件之外更新範圍時,使用'$ apply'。它強制摘要 – charlietfl

回答

1

$watch執行當前值和前一個摘要循環的值之間的平等比較。如果它們不同,則執行該功能。

如果由CookieHandler.get()返回的對象始終是相同的引用,那麼watch函數將永遠不會被調用。即使您更新該對象的屬性。

數組是一個壞主意,因爲它們通常總是一個新對象,JavaScript會將它們視爲從不相等。

您可以將對象/數組序列化爲JSON並使用該值,但如果鍵/值順序發生更改,則這不起作用。

它看起來像你試圖監視當前用戶更改。假設你有一個用戶的唯一標識符,那麼你可能想嘗試這樣的事情。

$scope.$watch(
    function() { 
     var user = CookieHandler.get(); 
     return (typeof user === 'undefined') ? 0 : user.id; 
    }, 
    function(newValue, oldValue) { 
    if(newValue !== oldValue) { 
     $scope.user = CookieHandler.get(); 
    } 
    } 
); 

請注意,我呼叫.get()兩次。我不知道你的服務是如何運作的。也許這是不可能的,但重點是看一個容易比較的價值。

+0

很好,這是有效的,並且朝着正確的方向邁出了一步,儘管由於某種原因它在頁面刷新上似乎很脆弱。它給了我一些開始雖然,謝謝!我不確定我是否理解三元運算符。基本上,觀察者在'user.id'上設置,並且如果'user.id'未定義則被設置爲0。那麼,每當'$ digest'循環運行時,這個觀察器會檢查CookieHandler.get()是否爲'user.id'返回一個新值? – user2936314

+1

@ user2936314是的,我不知道'get()'返回了什麼。所以我只是假設你使用整數作爲ID,並且將undefined默認爲0.基本思路是確保手錶使用可比較的值。對象/數組在JS中不容易比較。字符串/數字更容易與觀察者一起使用。 – cgTag