Angularjs 更新服务对象时,$watch未更新

Angularjs 更新服务对象时,$watch未更新,angularjs,angularjs-service,angularjs-controller,angularjs-watch,Angularjs,Angularjs Service,Angularjs Controller,Angularjs Watch,我发现了一个令人困惑的情况,$scope.watch没有像我预期的那样触发。我希望你们中的一些AngularJS爱好者能够帮助我们了解为什么AngularJS在$scope.watch和服务对象上表现得如此独特。值得注意的是,这是在我处理离子骨架时发现的 下面是我正在运行的示例,它按预期工作(用于在会话期间维护状态信息) TL;医生: 当我在服务中使用新的userObject(currentUser=new userObject();)更新currentUser时,Watch不会在控制器上启动。

我发现了一个令人困惑的情况,$scope.watch没有像我预期的那样触发。我希望你们中的一些AngularJS爱好者能够帮助我们了解为什么AngularJS在$scope.watch和服务对象上表现得如此独特。值得注意的是,这是在我处理离子骨架时发现的

下面是我正在运行的示例,它按预期工作(用于在会话期间维护状态信息)

TL;医生: 当我在服务中使用新的userObject(currentUser=new userObject();)更新currentUser时,Watch不会在控制器上启动。如果我改为更新对象的每个单独属性,它会触发

currentUser.name = 'Foo'; 
currentUser.email = 'foo@bar.com';
我正在寻求有关原因的指导,以便更好地理解

代码 服务(工作) 控制器 看法 结果 在此场景中,init(null)上的加载替换为“”和$scope.watch从不触发。我的期望是手表应该对物体进行深度观察,当我用新的物体替换物体时,它应该触发物体的变化并触发手表

我唯一能想到的是,当我用一个新对象替换currentUser对象时,$watch的委托在该对象上也丢失了。有人知道我该怎么说吗


当您给
$watch
一个字符串时,它会检查角度函数中的变量,因为您的作用域中没有
UserService.currentUser
,那么该watcher函数将永远不会被触发

为了使手表正常工作,您需要使用函数而不是
字符串
,然后该函数将返回一个表达式。通过将其添加到watcher函数中,以便在每个摘要循环中对其进行评估,并执行脏检查。如果值发生变化,它将触发watcher函数

代码

$scope.$watch(function(){
   return UserService.currentUser;
}, function(newVal, oldVal) {
    if (newVal !== oldVal ){
        dashboard.user = newVal;
    }
});

但由于除了如何在服务中更新currentUser之外,没有任何更改,因此不确定这将如何影响结果。我将给它一个旋转和更新,看看它被调用的方式是否会改变它的行为方式,同时监视对象被完全替换。更新:使用函数方法而不是字符串不起作用,因为问题似乎是服务没有触发监视事件(仅当对象被替换为新对象时。当您更新单个属性时,它工作正常,这就是为什么我如此困惑的原因)
angular.module('app.controllers')
.controller('DashboardCtrl', function ($scope, UserService) {
    var dashboard = this;

    dashboard.user = UserService.currentUser;

    $scope.$watch('UserService.currentUser', function(newVal, oldVal) {
        if (newVal !== oldVal ){
            dashboard.user = newVal;
        }
    });

    var createdUser = UserService.createUser(
        1,
        'user1',
        'asdf@asdf.com',
        'Test User',
        new Date()
    );
    UserService.setCurrentUser(createdUser);
});
<div ng-controller="DashboardCtrl as dashboard">
    <span bind="dashboard.user.fullName">Loading</span>
</div>
angular.module('app.services')
.service( 'UserService', function() {
    var userObject = function(){
        return {
            id: null,
            username: null,
            email: null,
            fullName: null,
            modified: null
        }
    };
    var currentUser = new userObject();

    var createUser = function(id, username, email, fullName, modified ){
        var newUserObject = new userObject();
        newUserObject.id = id;
        newUserObject.username = username;
        newUserObject.email = email;
        newUserObject.fullName = fullName;
        newUserObject.modified = (modified) ? modified : new Date();
        return newUserObject;
    };

    var setCurrentUser = function(userObj){
        console.log('First');
        console.dir(currentUser);

        // Set original 'currentUser' with a new UserObject passed by controller
        currentUser = userObj;            

        console.log('Second');
        console.dir(currentUser);

        return currentUser;
    };

});
$scope.$watch(function(){
   return UserService.currentUser;
}, function(newVal, oldVal) {
    if (newVal !== oldVal ){
        dashboard.user = newVal;
    }
});