Skip to main content
 首页 » 编程设计

angularjs之服务变量未在 Controller 中更新

2024年11月24日9jackei

我有一个位于 ng-view 之外的 NavbarCtrl。我有一个登录 Controller ,它与服务对话以让用户登录。用户登录后,我希望导航栏更新为用户的电子邮件地址。但是,在我的一生中,一旦用户登录,我似乎无法让 Navbar 范围使用加载到我的“Auth”服务中的数据进行更新。

这是我的主要 index.html:

<div class="navbar navbar-inverse navbar-fixed-top"> 
 
        <div class="navbar-inner"> 
            <div class="container"> 
                <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> 
                    <span class="icon-bar"></span> 
                    <span class="icon-bar"></span> 
                    <span class="icon-bar"></span> 
                </a> 
                <a class="brand" href="#">Brim</a> 
 
                <div class="pull-right"  ng-controller="NavbarCtrl"> 
                    <div ng-click="refresh()">hello</div> 
                    {{ user.email }} 
                </div> 
            </div> 
        </div> 
 
    </div> 
 
    <div class="container" ng-view> 

还有我的服务:
.factory('Auth', function($resource) { 
    var authenticated = false; 
    var user = {}; 
    return { 
        isAuthenticated: function () { 
            return authenticated; 
        }, 
        getUser: function() { 
            return user; 
        }, 
        login: function(loginUser, callback) { 
            user =  {email:'email@email.com'} 
            authenticated = true; 
            callback(true); 
            //actual code for logging in taken out for brevity 
        } 
    } 
}) 

还有我的登录和导航栏 Controller :
function LoginCtrl($scope, $location, Auth) { 
 
$scope.login = function() { 
    Auth.login($scope.user, function(success) { 
        if(success) $location.path('/dashboard'); 
        //console.log(Auth.getUser()) 
    }); 
} 
 
} 
 
function NavbarCtrl($scope, Auth)  { 
 
//thought this should work 
$scope.user = Auth.getUser(); 
 
//experimenting unsuccessfully with $watch 
$scope.$watch(Auth.isAuthenticated(),function () { 
    $scope.user = Auth.getUser() 
}) 
 
//clicking on a refresh button is the only way I can get this to work 
$scope.refresh = function() { 
    $scope.user = Auth.getUser() 
} 
} 

根据我的研究,我会认为 $scope.user = Auth.getUser();会工作,但它不是,我完全不知道如何在用户登录时更新我的​​导航栏。在此先感谢您的帮助。

请您参考如下方法:

更新 :好吧,你每天都在学习新东西......只需删除 ()查看函数的结果:

$scope.$watch(Auth.isAuthenticated, function() { ... }); 

Updated fiddle

在这个 fiddle 中,注意'watch1' 和'watch3' 如何在 $scope.isAuthenticated 的值时再次触发。变化。

所以,这是 的通用技术。监视对服务定义的原始值的更改 :
  • 定义返回原始值
  • 的 API/方法
  • $watch那个方法

  • 监视在服务上定义的对象或数组的更改 :
  • 定义返回(引用)对象/数组的 API/方法
  • 在服务中注意只修改对象/数组,不要重新赋值。例如,不要这样做:user = ...;而是这样做:angular.copy(newInfo, user)或者这个:user.email = ...
  • 通常,您会为该方法的结果分配一个本地 $scope 属性,因此 $scope 属性将是对实际对象/数组的引用
  • $watch 范围属性

  • 例子:
    $scope.user = Auth.getUser(); 
    // Because user is a reference to an object, if you change the object 
    // in the service (i.e., you do not reassign it), $scope.user will 
    // likewise change. 
    $scope.$watch('user', function(newValue) { ... }, true); 
    // Above, the 3rd parameter to $watch is set to 'true' to compare 
    // equality rather than reference.  If you are using Angular 1.2+ 
    // use $watchCollection() instead: 
    $scope.$watchCollection('user', function(newValue) { ... }); 
    

    原答案:

    要查看函数的结果,您需要向 $watch 传递一个包装该函数的函数:
    $scope.$watch( function() { return Auth.isAuthenticated() }, function() { ... }); 
    

    Fiddle .在 fiddle 中,请注意当 $scope.isAuthenticated 的值时只有 'watch3' 会第二次触发。变化。 (它们最初都触发,作为 $watch 初始化的一部分。)