24

我有一个在 ng-view 之外的 NavbarCtrl。我有一个登录控制器,它与服务对话以使用户登录。用户登录后,我希望导航栏使用用户的电子邮件地址进行更新。但是对于我的生活,我似乎无法让导航栏范围更新用户登录后加载到我的“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
        }
    }
})

还有我的登录和导航栏控制器:

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(); 会起作用,但事实并非如此,我完全不知道如何在用户登录时更新我的​​导航栏。提前感谢您的帮助。

4

3 回答 3

54

更新:嗯,你每天都会学到一些新东西......只需删除()以观察函数的结果:

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

Updated 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() { ... });

小提琴。在小提琴中,请注意当值$scope.isAuthenticated更改时,只有“watch3”第二次触发。(它们最初都会触发,作为 $watch 初始化的一部分。)

于 2013-03-13T17:09:43.280 回答
0

尝试改变

$scope.$watch(Auth.isAuthenticated(),function () { $scope.user = Auth.getUser() })

$scope.$watch(Auth.isAuthenticated(),function () { $scope.user = Auth.getUser() }, true)

详细解释请看 AungularJs $watch 文档,默认值为 false 表示 Angular 通过引用检测第一个参数值的变化,而传递 true 表示通过相等进行检查。作为函数的参数,检查总是返回 false,因为对函数的引用总是相同的。

于 2013-03-13T08:53:33.617 回答
0

用作user变量名通常不是一个好主意。我曾经改变过它,currentUser一切都对我有用。

于 2016-05-25T19:45:07.430 回答