2015-10-17 80 views
1

我是Angular的初學者。我堅持以角度js更新$ scope變量。我創建了一個服務名稱「Main」,我想用它來更新我的$ scope.token。我已經使用$ scope.apply和$ scope.digest但收到以下錯誤:使用角度js服務更新範圍變量

> Error: [$rootScope:inprog] $apply already in progress 
> http://errors.angularjs.org/1.4.4/$rootScope/inprog?p0=%24apply 
>  at angular.js:68 
>  at beginPhase (angular.js:16273) 
>  at Scope.$apply (angular.js:16014) 
>  at new <anonymous> (controllers.js:11) 
>  at Object.invoke (angular.js:4473) 
>  at extend.instance (angular.js:9093) 
>  at nodeLinkFn (angular.js:8205) 
>  at compositeLinkFn (angular.js:7637) 
>  at compositeLinkFn (angular.js:7641) 
>  at publicLinkFn (angular.js:7512) 

以下是代碼片段。

的index.html

<div class="navbar-collapse collapse"> 
        <ul class="nav navbar-nav"> 
         <li><a ng-href="#/">Home</a></li> 
         <li data-ng-show="token"><a ng-href="#/me">Me</a></li> 
         <li data-ng-hide="token"><a ng-href="#/signin">Signin</a></li> 
         <li data-ng-hide="token"><a ng-href="#/signup">Signup</a></li> 
         <li ><a data-ng-show='true' ng-click="logout()">Logout</a></li> 
        </ul> 
       </div> 

services.js

'use strict'; 

angular.module('angularRestfulAuth') 
    .factory('Main', ['$http', '$localStorage','$cookies', function($http, $localStorage,$cookies){ 
     return { 
      tokShowhide: function(data) { 
       if($cookies.get('sid')!=undefined) 
       return true; 
       else 
       return false; 
      } 
}; 
}]); 

在controllers.js

$scope.$apply(function() { 
      $scope.token = Main.tokShowhide(); 
     }); 

How do I update $scope variable and reflect its change in my view (index.html) ??

+0

使用Angular本身時,不需要使用'apply()'。只有在使用不支持Angular的異步事件(本地DOM事件,不帶'$ http的Ajax等)時才需要它。 –

+0

解釋爲什麼你認爲你需要'apply()'。如果你設置了cookie,沒有什麼會改變這個值 – charlietfl

+0

也許你可以使用'$ timeout' – geckob

回答

0

你在哪個上下文中執行那個$apply()

如果你這樣做你的ng-click功能之一內,正在加載的控制器上時(比如你點擊一個ng-href一個鏈接後,當您在導航),是沒有必要使用$apply(),因爲你已經在angularJs上下文中執行了。

例如,如果您正在使用jquery事件,則需要在超出角上下文時調用$apply()

所有angularjs事件(ng-clickng-mouseoverng-mouseenterng-class)是在純JavaScript不同的事件或功能加上$apply()通話的外包裝,所以角知道它必須檢查$watchers和更新視圖。 Angular的內置服務也是如此。

總之,你只需要直接做

$scope.token = Main.tokShowhide(); 

+0

感謝你的答案。我試過「scope.token = Main.tokShowhide();」 。但要查看瀏覽器中的更改,始終需要刷新瀏覽器。它不會自動在我的視圖index.html中自動更新。 – romir

+0

你需要使用ng-show和ng-hide,而不是data-ng-show和data-ng-hide –

+0

@ Gonzalo.- data-ng-show和ng-show在語義上是相同的。 – buzzsaw

0

您的錯誤是由您在控制器中致電$scope.$apply()引起的。

取而代之的是:

$scope.$apply(function() { 
    $scope.token = Main.tokShowhide(); 
}); 

只是這樣做:

$scope.token = Main.tokShowhide(); 
0

我通常使用$範圍$適用()如果通過非角的內置服務的其他一些更新範圍內的變量。大多數情況下,當我使用類似jQuery的方法執行異步請求,然後想要使用結果更新作用域變量時,我會看到這一點。然而,如果您只是更新一個範圍變量而不做任何異步操作,Angular具有雙向數據綁定,這些更新通常會在視圖更改後自動更新。

如果由於某種原因你更新了一個範圍變量,但它沒有在你的視圖上更新,你可以嘗試使用$ scope。$適用(),但我更喜歡,而不是注入$超時,然後換你的$超時服務中更新範圍的變量,就像這樣:

$timeout(function(){ 
    $scope.token = Main.tokShowhide(); 
}) 

這也將引發新的消化週期和更新您的看法這些新的範圍值和接收到的錯誤描述了正在進行的摘要循環。