angularjs:如何观察全局变量的变化?
我想观看angularjs:如何观察全局变量的变化?,angularjs,Angularjs,我想观看myApp.myUser的更改: <html ng-app="myApp"> <head> <script src="js/vendor/angular/angular.min.js"></script> <script src="js/app2.js"></script> </head> <body> <div id="users" ng-controller="users
myApp.myUser
的更改:
<html ng-app="myApp">
<head>
<script src="js/vendor/angular/angular.min.js"></script>
<script src="js/app2.js"></script>
</head>
<body>
<div id="users" ng-controller="usersController">
<h4>usersController</h4>
test = {{myUser}}
</div>
<div id="tasks" ng-controller="tasksController">
<button ng-click="clickMe()">cliquez ici </button>
</div>
</body>
</html>
我用控制台试过:
myApp.myUser = {id:2, username:'jack'}
没什么。
然后,我尝试使用tasksController
$scope.clickMe = function() {
myApp.myUser = {id:2, username:'jack'}
}
我的观点没有改变
如的文档中所示,第一个参数必须是监视表达式
——也就是说,一个角度表达式(一个字符串
),描述应监视$scope
中的值
您的值myApp.myUser
不是$scope
的一部分,无法通过$watch
访问。解决方案是将对象移动到类似$scope.myUser
的位置,然后调用$scope.watch('myUser',function(){console.log('userChanged');})代码>
请注意:
$watch
如果你安装了很多手表,那么它可能会很贵。您通常希望为用户可以在视图上操作的数据设置一个监视,但不希望为通过代码直接加载的数据设置监视
- 如果表达式指向一个对象,
$watch
将只跟踪对引用的更改,因此$scope.myUser={}
将触发侦听器回调,但$scope.myUser.username='jack'代码>不会。您可以传递第三个参数true
,使其检查深度不平等性,但对于复杂对象或大量手表,这会变得更加昂贵
如的文档中所示,第一个参数必须是一个监视表达式
——即一个角度表达式(一个字符串
),描述应监视$scope
中的值
您的值myApp.myUser
不是$scope
的一部分,无法通过$watch
访问。解决方案是将对象移动到类似$scope.myUser
的位置,然后调用$scope.watch('myUser',function(){console.log('userChanged');})代码>
请注意:
$watch
如果你安装了很多手表,那么它可能会很贵。您通常希望为用户可以在视图上操作的数据设置一个监视,但不希望为通过代码直接加载的数据设置监视
- 如果表达式指向一个对象,
$watch
将只跟踪对引用的更改,因此$scope.myUser={}
将触发侦听器回调,但$scope.myUser.username='jack'代码>不会。您可以传递第三个参数true
,使其检查深度不平等性,但对于复杂对象或大量手表,这会变得更加昂贵
我建议您通过在服务中将变量声明为
var myApp = angular.module('myApp', []);
myApp.factory('DataService',function(){
var myUser ={id:1, username:'john'};
var tasks;
var users;
return{
users:users,
tasks:tasks,
myUser:myUser
}
});
myApp.controller('usersController', function($scope,DataService) {
$scope.myUser = DataService.myUser;
console.log(DataService.myUser);
$scope.$watch(DataService.myUser, $scope.userChanged);
$scope.userChanged = function() {
console.log('userChanged');
}
});
myApp.controller('tasksController', function($scope,DataService) {
$scope.tasks = DataService.tasks;
$scope.clickMe = function() {
DataService.myUser = {id:2, username:'jack'}
}
});
我建议您通过在服务中将变量声明为
var myApp = angular.module('myApp', []);
myApp.factory('DataService',function(){
var myUser ={id:1, username:'john'};
var tasks;
var users;
return{
users:users,
tasks:tasks,
myUser:myUser
}
});
myApp.controller('usersController', function($scope,DataService) {
$scope.myUser = DataService.myUser;
console.log(DataService.myUser);
$scope.$watch(DataService.myUser, $scope.userChanged);
$scope.userChanged = function() {
console.log('userChanged');
}
});
myApp.controller('tasksController', function($scope,DataService) {
$scope.tasks = DataService.tasks;
$scope.clickMe = function() {
DataService.myUser = {id:2, username:'jack'}
}
});
不要在myApp
变量上使用属性,因为该变量实际上包含了所有AngularJS功能,因此有发生冲突的风险
在AngularJS中存储数据有两个选项:
$rootScope
-操作与$scope
类似,但它连接到整个应用程序,而不仅仅是当前控制器
。这是首选方法,因为它使代码模块化且可重用。在您的情况下,您可以设置一个数据服务
那看起来像
myApp.factory('dataService', function() {
// this is simplified for illustration, see edit below
return {
myUser: {id: 1, username: 'john'},
};
});
myApp.controller('usersController', function($scope, dataService) {
$scope.myUser = dataService.myUser;
});
编辑:
正如在评论中所讨论的,这带来了另一个潜在的绑定问题,因为我使用了一个可以通过userService.myUser={}覆盖的文本值代码>。更好的数据服务将提供更可靠的双向绑定,如下所示:
myApp.factory('dataService', function() {
var users = [
{ id: 1, username: 'john' }
];
return {
getUser: function(id) {
for (i=0; i<users.length; i++) {
if (users[i].id === id) {
return users[i];
}
}
}
};
});
myApp.controller('usersController', function($scope, dataService) {
$scope.myUser = dataService.getUser(1);
});
myApp.factory('dataService',function()){
变量用户=[
{id:1,用户名:'john'}
];
返回{
getUser:函数(id){
对于(i=0;i不要在myApp
变量上使用属性,因为该变量实际上包含所有AngularJS功能,并且有发生冲突的风险
在AngularJS中存储数据有两个选项:
$rootScope
-操作与$scope
类似,但它连接到整个应用程序,而不仅仅是当前控制器
。这是首选方法,因为它使代码模块化且可重用。在您的情况下,您可以设置数据服务
那看起来像
myApp.factory('dataService', function() {
// this is simplified for illustration, see edit below
return {
myUser: {id: 1, username: 'john'},
};
});
myApp.controller('usersController', function($scope, dataService) {
$scope.myUser = dataService.myUser;
});
编辑:
正如在评论中所讨论的,这带来了另一个潜在的绑定问题,因为我使用了一个可以通过userService.myUser={};
覆盖的文本值。更好的数据服务将提供更可靠的双向绑定,如下所示:
myApp.factory('dataService', function() {
var users = [
{ id: 1, username: 'john' }
];
return {
getUser: function(id) {
for (i=0; i<users.length; i++) {
if (users[i].id === id) {
return users[i];
}
}
}
};
});
myApp.controller('usersController', function($scope, dataService) {
$scope.myUser = dataService.getUser(1);
});
myApp.factory('dataService',function()){
变量用户=[
{id:1,用户名:'john'}
];
返回{
getUser:函数(id){
对于(i=0;i同意,但也希望敦促阅读此问答的任何人小心JS中的赋值操作。此示例使用$scope.myUser=userService.myUser
行缓存引用,这是完全正确的,但前提是任何操作userService.myUser
的代码都不会更改us的引用值erService.myUser
(例如,userService.myUser={id:2,用户名:'jane'};
)@Jessemano,你说得对。我用了一个简单的例子来说明这一点,但更好的解决方案是在return
语句之前设置对象,然后返回getter和setter函数,以便引用保持完整。我在回答中添加了一条注释来说明这一点。是的!我之所以提出这个问题,主要是因为问题(以及迄今为止的一个答案)具有用新对象引用覆盖一个对象引用的代码,似乎期望只有旧引用的观察者会以某种方式观察新引用状态。同意。为了更好地解释,我再次更新了答案,因为考虑到问题的性质,我的简化版本可能会在ut澄清