【发布时间】:2015-11-10 14:16:52
【问题描述】:
我发现了一个令人困惑的情况,其中 $scope.watch 没有像我预期的那样触发。我希望你们中的一些 AngularJS 爱好者可以帮助阐明为什么 Angular 对 $scope.watch 和 Service 对象的行为如此特殊。请注意,这是在我弄乱 Ionic 框架时发现的。
以下是我正在运行的示例,它按预期工作(用于在会话期间维护状态信息。)
TL;DR: 当我在服务中使用新的 userObject (currentUser = new userObject();) 更新 currentUser 时,Watch 不会在控制器上触发。如果我改为更新对象的每个单独属性,它确实会触发。
currentUser.name = 'Foo';
currentUser.email = 'foo@bar.com';
我正在寻求有关原因的指导,以便更好地理解。
代码
服务(工作)
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);
setUserId(userObj.id);
setUsername(userObj.username);
setEmail(userObj.email);
setFullName(userObj.fullName);
setModifiedDate(userObj.modified);
console.log('Second');
console.dir(currentUser);
return 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>
结果
哇哦!加载在初始化时被替换为 ''(null),并在手表更新后立即使用 'Test User' (比人眼快,除非调试)
中断场景
上面的代码效果很好。但是,我想尝试通过创建一个新的 UserObject 然后将该对象设置为“当前用户”来减少重复工作来减少代码。我所做的更改如下(视图和控制器不变):
服务(损坏)
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;
};
});
结果
在 init (null) 上加载被替换为 '' 并且 $scope.watch 在这种情况下永远不会触发。我的期望是手表应该对对象进行深入观察,当我用新对象替换对象时,它应该触发对象发生变化并触发手表。
我唯一能想到的是,当我用新对象替换 currentUser 对象时,$watch 的委托也会在该对象上丢失。有没有人知道我如何分辨?
呸。
【问题讨论】:
标签: angularjs angularjs-service angularjs-controller angularjs-watch