我发现了一个令人困惑的情况,其中$ scope.watch没有像我期望的那样触发。我希望你们中的一些AngularJS buff可以帮助解释为什么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>
嗬!加载在init上替换为&#39;&#39;&#39; (null)并在手表更新后立即使用“测试用户”#39; (除非调试,否则比人眼更快)
上面的代码效果很好。但是,我想通过创建一个新的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;
};
});
正在使用&#39;&#39;替换在init(null)和$ scope.watch从不在这种情况下触发。我的期望是手表应该对物体进行深入观察,当我用新物体替换物体时,它应该触发物体改变并触发手表。
我唯一可以想到的是,当我用new对象替换currentUser对象时,$ watch的委托也会丢失在该对象上。有谁知道我怎么说?
呼。
答案 0 :(得分:2)
当你给$watch
一个字符串时,它会检查角度函数中的变量,因为你的范围内没有UserService.currentUser
,那么观察者函数永远不会被触发。
为了让你的手表正常工作,你需要使用函数而不是string
,然后该函数将返回一个表达式。通过将其添加到观察器功能中,以便在每个摘要周期中对其进行评估。将执行脏检查。如果值得到改变,它将触发观察者功能
<强>代码强>
$scope.$watch(function(){
return UserService.currentUser;
}, function(newVal, oldVal) {
if (newVal !== oldVal ){
dashboard.user = newVal;
}
});