Use `this.$watch` instead of `$scope.$watch` with 'Controller As'

后端 未结 4 1813
Happy的楠姐
Happy的楠姐 2021-02-20 06:44

Currently I am using the Controller As format for scoping controllers.

This works great for keeping the scope of values on the views clear and easy to follo

相关标签:
4条回答
  • 2021-02-20 07:20

    Even with the controllerAs format, the $scope is there.

    In fact what controllerAs does is bind the controller instance's this to the $scope.
    E.g. controller="myController as myctrl" does (behind the scenes): $scope.myctrl = this (where this refers to the myController instance).

    So, you can just inject and use the $scope for watches:

    .controller('myController', function ($scope, contacts) {
        this.contacts = contacts;
    
        $scope.$watch(function () {
            return contacts;
        }, function (newValue, oldValue) {...});
    });
    
    0 讨论(0)
  • 2021-02-20 07:22
    $scope.$watch("contact", callback, true) // true makes it a deep/recursive watch
    
    0 讨论(0)
  • 2021-02-20 07:22

    Try this,

     $scope.$watch(angular.bind(this, function () {
                return this.contacts;
            }), function (newValue, oldValue) {
                console.log((newValue + '  -  ' + oldValue));
            });
    
    0 讨论(0)
  • 2021-02-20 07:28

    Others written clearly about why $scope is generally still required. But not how to actually watch your variables in the case of your example to properly watch the local variable "contacts" you must identify it by the controller namespace.

    So:

    $scope.$watch('myctrl.contacts', function(newValue, oldValue) {
           console.log({older: oldValue, newer:newValue});
        });
    

    The idea of using the local namespace is to prevent mutation if you create child controllers inside another controller. The nice benefit of this is that a parent controller can watch all the spaces inside its scope.

    Lets say that the initial html looked something like:

    <div ng-app="myApp" ng-controller="myController as myctrl">
      <div ng-controller="listController as mylist">
        <ul>
            <li ng-repeat="contact in myctrl.contacts">
                <input type="text" ng-model="contact.name.first" />
            </li>
        </ul>
      </div>
    </div>
    

    and the js:

    angular.module('myApp',[])
    .controller('myController',['$scope',function(contacts) {
    
        $scope.$watch('mylist.contacts', function(newValue, oldValue) {
           console.log({older: oldValue, newer:newValue});
        })
    .controller('listController',['contacts',function(contacts) {
        this.contacts = contacts;
        });
    }]);
    

    Now the main controller is watching activity in a nested controller... pretty nifty.

    0 讨论(0)
提交回复
热议问题