更新$ scope并在视图中反映

时间:2013-08-27 13:42:26

标签: authentication angularjs view angularjs-scope

在我的angularjs应用程序中,我正在为每个页面渲染我的“导航栏”div。

用户登录并重定向到详细信息页面后,我想要更新未反映到视图中的$ scope。

为了反映$ scope的变化,我使用$ scope。$ apply()调用$ digest。似乎它没有更新,$ scope更新仍未反映在我看来。

我的代码如下所示:

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之类的其他问题,但在我的案例中没有用。

3 个答案:

答案 0 :(得分: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;
        }
    });
}

查看:

<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>

答案 1 :(得分:0)

主要问题是您使用的是两个不同的控制器。每个控制器都有自己的范围(即范围不是全局的),因此当您在ProductDetails中更改showLogin时,只有本地范围发生变化,而不是NavCtrl。

您可以重写它以使用一个控制器,或者在控制器之间传递数据,有几种方法可以做到这一点:

  • 您可以在$ rootScope上设置数据。 rootScope是一个全局范围,所有控制器都可以访问,并且您始终可以在模板中使用。我建议将rootScope保持在最低限度,因为rootScope在任何地方都是共享的,你最终可能会遇到大量的变量。
  • 您可以通过服务传递数据。每个服务只创建一个实例,因此不同的控制器可以访问相同的服务并获得相同的数据。
  • 您可以使用。$ broadcast向任何子控制器发送信号。这可能也是最好的保持在最低限度,很多广播迟早会减慢你的速度(虽然限制应该很高)。

答案 2 :(得分: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>