2013-08-27 42 views
1

在我的angularjs應用程序中,我爲每個頁面呈現「導航欄」div。

用戶登錄並重定向到詳細信息頁面後,我希望我正在更新$範圍,這不會反映到視圖中。

爲了反映$ scope的變化,我使用$ scope。$ apply()調用$ digest。似乎沒有更新和$範圍更新仍然沒有反映在我看來。

我的代碼看起來像下面:

CONTROLLER: 

function NavCtrl($scope){ 
    //as isAuth false 
    $scope.showLogin = true; 
    $scope.showLogout = false; 
} 

function ProductDetails($scope){ 
    //as isAuth true 
    $scope.showLogin = false; 
    $scope.showLogout = true; 

    if (!$scope.$$phase) { 
     //$digest or $apply to reflect update of scope update 
     $scope.$apply(); 
    } 
} 

VIEW: 

<div id="navigation-bar" ng-controller="NavCtrl"> 
    <li ng-show="showLogin"><a href="/login">Login</a></li> 
    <li ng-show="showLogout"><a href="/logout">Logout</a></li> 
</div> 

我做錯了嗎?我錯過了任何觀點嗎?順便說一句,我經歷了其他問題,如AngularJS $scope updates not reflected in the view,但它並沒有幫助我的情況。

回答

0

問題是你應該爲此使用單個控制器。這裏是一個控制器的例子,根據他的connected範圍變量顯示正確的菜單。該值使用AJAX或代碼中的其他位置設置。

控制器:

function NavCtrl($scope, $rootScope){ 
    $scope.showLogin = true; 
    $scope.showLogout = false; 

    $rootScope.$watch("connected", function() { 
     if ($rootScope.connected) { 
      $scope.showLogin = false; 
      $scope.showLogin = true; 
     } else { 
      $scope.showLogin = true; 
      $scope.showLogin = false; 
     } 
    }); 
} 

VIEW:

<div id="navigation-bar" ng-controller="NavCtrl"> 
    <li ng-show="showLogin"><a href="/login">Login</a></li> 
    <li ng-show="showLogout"><a href="/logout">Logout</a></li> 
</div> 
<a href="javascript:" ng-click="$root.connected = true">Connect me</a> 
+0

我在設置$ scope.connected = true;在我的「ProductDetails」控制器中?這可以嗎?在我看來,它仍然沒有反映出來。 – arnold

+0

否,因爲它不在相同的範圍內。您可以在NavCtrl中使用$ rootScope.connected並更改任何控制器中的值。這樣,您將使用根作用域。我改變了我的答案,告訴你如何。 –

0

的主要問題是,你正在使用兩種不同的控制器。每個控制器都有自己的作用域(即作用域不是全局作用域),所以當你改變你的ProductDetails中的showLogin時,它只是本地作用域的變化,而不是NavCtrl的作用域。

您可以重寫它使用一個控制器或者控制器之間傳遞數據,有幾種方法可以做到這一點:

  • 您可以設置在$ rootScope數據。 rootScope是全局控制器可以訪問的全局範圍,並且您始終可以在模板中使用它。我建議儘量保持rootScope的最低限度,因爲rootScope在任何地方都是共享的,並且最終可能會產生大量的變量。
  • 您可以通過服務傳遞數據。每個服務只創建一個實例,因此不同的控制器可以訪問相同的服務並獲取相同的數據。
  • 您可以使用。$ broadcast向任何子控制器發送信號。這可能也是最好的保持在最低限度,很多廣播將遲早會讓你失望(儘管限制應該很高)。
0

我建議一個AuthUserService跟蹤登錄狀態,並注入該服務到您的NavCtrl和任何其他控制器,需要了解用戶:

.factory('AuthUserService', ['$http','$q', 
function($http, $q) { 
    var user = {}; 
    return { 
     user: function() { 
      return user; 
     }, 
     login: function(user_credentials) { 
      $http.post('/login', user_credentials).then(
       function(response) { 
        angular.copy(response.data, user); 
        ... 
      }); 
     }, 
     logout: function() { ... 
     } 
    } 
}]) 

.controller('NavCtrl', ['AuthUserService','$scope', 
function(AuthUserService, $scope) { 
    $scope.user = AuthUserService.user(); 
    $scope.$watch('user.name', function(name) { 
     if(name) { 
      $scope.loggedIn = true; 
     } else { 
      $scope.loggedIn = false; 
     } 
    }); 
}]) 

<div ng-controller="NavCtrl"> 
    <li ng-hide="loggedIn"><a href="/login">Login</a></li> 
    <li ng-show="loggedIn"><a href="/logout">Logout</a></li> 
</div> 
相關問題