angularjs:如何观察全局变量变化?

时间:2016-08-22 22:03:30

标签: 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="usersController">
    <h4>usersController</h4>
    test = {{myUser}}
    </div>        
    <div id="tasks" ng-controller="tasksController">
    <button ng-click="clickMe()">cliquez ici </button>
    </div>
</body>
</html>

和app2.js:

var myApp = angular.module('myApp', []);
myApp.users = {};
myApp.tasks = {};
myApp.myUser = {id:1, username:'john'}

myApp.controller('usersController', function($scope) {
    $scope.myUser = myApp.myUser;
    $scope.$watch(myApp.myUser, $scope.userChanged);
    $scope.userChanged = function() {
        console.log('userChanged');
    }   
});

myApp.controller('tasksController', function($scope) {
    $scope.tasks = myApp.tasks;
    $scope.clickMe = function() {
        myApp.myUser = {id:2, username:'jack'}
    }
});

我用控制台尝试了这个:

myApp.myUser = {id:2, username:'jack'}

无。 然后我尝试用tasksController

通过AngularJS传递它
$scope.clickMe = function() {
    myApp.myUser = {id:2, username:'jack'}
}

我的观点没有任何改变!

http://jsfiddle.net/halirgb/Lvc0u55v/

3 个答案:

答案 0 :(得分:2)

我建议您通过在服务中将其声明为

来使用变量
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'}
        }
    });

答案 1 :(得分:2)

不要在myApp变量上使用属性,它实际上包含所有AngularJS功能,并且存在冲突风险。

您有几种在AngularJS中存储数据的选项:

  1. $rootScope - 与$scope一样操作,但是附加到整个应用程序,而不仅仅是当前的控制器。
  2. Services。这是首选方法,因为它使您的代码保持模块化和可重用。在您的情况下,您可以设置数据服务。
  3. 这看起来像......

    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);
    });
    

答案 2 :(得分:1)

$scope.$watch的文档中所示,第一个参数必须是watchExpression - 即一个Angular表达式(string),用于描述$scope中的值应该看。

您的值myApp.myUser不属于$scope$watch无法访问。解决方案是将您的对象移动到$scope.myUser之类的内容,然后调用$scope.$watch('myUser', function() { console.log('userChanged'); });

警告:

    如果你设置了很多手表,
  • $watch会很贵。您通常需要为用户可以在视图上操作的数据设置手表,而不是为您直接通过代码加载的数据设置。
  • 如果表达式指向某个对象,$watch只会跟踪对引用的更改,因此$scope.myUser = {};会触发侦听器回调,但$scope.myUser.username = 'jack';则不会。您可以传递第三个参数true以检查是否存在严重的不等式,但是对于复杂的对象或大量的手表来说,这会变得更加昂贵。