AngularJS $scope 没有观察来自 View 的变化

AngularJS $scope not watching changes from View

我有这个小示例,我希望在其中看到浏览器控制台中的日志消息,表明 $scope 观察器运行良好,但不幸的是情况并非如此。

<!doctype html>
<html ng-app="demo">

<head>
    <script src="bower_components/angular/angular.js"></script>
    <script>
    var app = angular.module('demo', ['ng']);
    app.controller('demoCtrl', function($scope) {
        var self = this;

        self.searchText = '';
        $scope.$watch('self.searchText', function(n, p) {
            console.log('searchText changed from', n, 'to', p);
        });

    });
    </script>
</head>

<body ng-controller="demoCtrl as ctrl">
    <input type="text" ng-model="ctrl.searchText" />
</body>

</html>

将您的 $watch 更改为:

$scope.$watch(function() {
    return self.searchText;
  }, function(n, p) {
    console.log('searchText changed from', n, 'to', p);
  });

form you used $scope.$watch 中观察表达式应该是作用域或根作用域的一部分。 所以你应该像这样改变你的代码:

<!doctype html>
<html ng-app="demo">

<head>
    <script src="bower_components/angular/angular.js"></script>
    <script>
    var app = angular.module('demo', ['ng']);
    app.controller('demoCtrl', function($scope) {
        var self = this;

        $scope.searchText = '';
        $scope.$watch('searchText', function(n, p) {
            console.log('searchText changed from', n, 'to', p);
        });

    });
    </script>
</head>

<body ng-controller="demoCtrl as ctrl">
    <input type="text" ng-model="searchText" />
</body>

</html>

或使用另一种形式并像这样更改您的代码:

<head>
    <script src="bower_components/angular/angular.js"></script>
    <script>
    var app = angular.module('demo', ['ng']);
    app.controller('demoCtrl', function($scope) {
        var self = this;

        self.searchText = '';
        $scope.$watch(function() { return self.searchText; }, function(n, p) {
            console.log('searchText changed from', n, 'to', p);
        });

    });
    </script>
</head>

<body ng-controller="demoCtrl as ctrl">
    <input type="text" ng-model="ctrl.searchText" />
</body>

</html>

您需要在 $scope.$watch(...) 中使用别名 ctrl(而不是 self):

<!doctype html>
<html ng-app="demo">

<head>
    <script src="bower_components/angular/angular.js"></script>
    <script>
    var app = angular.module('demo', ['ng']);
    app.controller('demoCtrl', function($scope) {
        var self = this;

        self.searchText = '';
        $scope.$watch('ctrl.searchText', function(n, p) {
            console.log('searchText changed from', n, 'to', p);
        });

    });
    </script>
</head>

<body ng-controller="demoCtrl as ctrl">
    <input type="text" ng-model="ctrl.searchText" />
</body>

</html>

当使用ng-controller="demoCtrl as ctrl"时,Angular创建一个link控制器上下文对象this进入范围:$scope.ctrl.

答案很简单-

Angular 监视作用域变量上的表达式,而不是控制器实例上的表达式。

要使代码正常工作,您需要按以下方式修改控制器代码

var self = this;

self.searchText = '';
$scope.self = this;
$scope.$watch('self.searchText', function(n, p) {
console.log('searchText changed from', n, 'to', p);
});