admin管理员组

文章数量:1394049

I have a controller in my Angular app:

(function (angular) {
    function MyController() {
        this.name = 'Dave';

        // I want to have code like this:
        /*
          $scope.$watch('name', function (newValue, oldValue) {
              console.log(oldValue, "changed to", newValue);
          });
        */
    }

    window.myApp = angular.module('myApp', [])
        .controller('MyController', [MyController]);
})(angular);

Is there a way to use the features of $scope.$watch when attaching values to the MyController prototype?

I did notice that in my code, if I add something like ng-controller="MyController as myCtrl", and change my $scope.$watch statement to $scope.$watch('myCtrl.name', ...), it'll work after I add the $scope dependency, but that feels like tying my controller to my views, which feels wrong.

Edit

To attempt to clarify on what I'm asking. My HTML is something like this:

<div ng-app="myApp">
  <div ng-controller="MyController as myCtrl">
    <input type="text" ng-model="myCtrl.name" />
    <p>{{myCtrl.helloMessage}}</p>
  </div>
</div>

My controller is something like this:

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    this.name = 'World';
    this.helloMessage = "Hello, " + this.name;

    var self = this;
    $scope.$watch('myCtrl.name', function () {
      self.helloMessage = "Hello, " + self.name;
    });
  }]);

That currently works, but as you can see, in the $watch call, I have to reference my controller by the controllerAs name from my view, which is less than ideal.

I've setup an example on Plunkr

I have a controller in my Angular app:

(function (angular) {
    function MyController() {
        this.name = 'Dave';

        // I want to have code like this:
        /*
          $scope.$watch('name', function (newValue, oldValue) {
              console.log(oldValue, "changed to", newValue);
          });
        */
    }

    window.myApp = angular.module('myApp', [])
        .controller('MyController', [MyController]);
})(angular);

Is there a way to use the features of $scope.$watch when attaching values to the MyController prototype?

I did notice that in my code, if I add something like ng-controller="MyController as myCtrl", and change my $scope.$watch statement to $scope.$watch('myCtrl.name', ...), it'll work after I add the $scope dependency, but that feels like tying my controller to my views, which feels wrong.

Edit

To attempt to clarify on what I'm asking. My HTML is something like this:

<div ng-app="myApp">
  <div ng-controller="MyController as myCtrl">
    <input type="text" ng-model="myCtrl.name" />
    <p>{{myCtrl.helloMessage}}</p>
  </div>
</div>

My controller is something like this:

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    this.name = 'World';
    this.helloMessage = "Hello, " + this.name;

    var self = this;
    $scope.$watch('myCtrl.name', function () {
      self.helloMessage = "Hello, " + self.name;
    });
  }]);

That currently works, but as you can see, in the $watch call, I have to reference my controller by the controllerAs name from my view, which is less than ideal.

I've setup an example on Plunkr

Share Improve this question edited Jul 31, 2014 at 20:21 Dave Long asked Jul 31, 2014 at 19:59 Dave LongDave Long 9,75914 gold badges63 silver badges89 bronze badges 1
  • What is the benefit of storing values on controller instances instead of scope? – Gildor Commented Aug 2, 2014 at 6:30
Add a ment  | 

3 Answers 3

Reset to default 4

$watch

Expression that is evaluated on each $digest cycle. A change in the return value triggers a call to the listener. Watch expression can be a sting or function.

  • string: Evaluated as expression
  • function(scope): called with current scope as a parameter.

example

angular.module('app', []).controller('MainCtrl', function($scope) {
  this.name = 'World'
  this.helloMsg = ''
  
  $scope.$watch(function() {
    return this.name
  }.bind(this), function(newName) {
    this.helloMsg = "Hello, " + newName
  }.bind(this))
});
<script src="https://ajax.googleapis./ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='app'>
  <div ng-controller='MainCtrl as ctrl'>
    <input type='text' ng-model='ctrl.name' />
    {{ ctrl.helloMsg }}
  </div>
</div>

You can avoid being bound to the view by using angular.bind in your watch, i.e.

$scope.$watch(angular.bind(this, function () {
    self.helloMessage = "Hello, " + self.name;
}));

https://docs.angularjs/api/ng/function/angular.bind

I might be wrong but I believe the $scope is automatically injected by angular.

Here's an example of a controller being declared:

var myApp = angular.module('myApp',[]);

myApp.controller('GreetingController', ['$scope', function($scope) {
      $scope.greeting = 'Hola!';
}]);

Notice how $scope dependency is declared '$scope' and injected function($scope)

In other words, should yours look something like this ?

function MyController($scope) {}

window.myApp = angular.module('myApp', [])
        .controller('MyController', ['$scope', MyController($scope)]);

EDIT:

I understand now. I've never had a need to use "controller as" but why not do it like this ?

<div ng-app="myApp">
  <div ng-controller="MyController">
    <input type="text" ng-model="name" />
    <p>{{helloMessage}}</p>
  </div>
</div>

angular.module('myApp', [])
  .controller('MyController', ['$scope', function ($scope) {
    this.name = 'World';
    this.helloMessage = "Hello, " + this.name;

    var self = this;
    $scope.$watch('name', function () {
      self.helloMessage = "Hello, " + self.name;
    });
  }])

本文标签: javascriptUsing scopewatch when using this scope in controllerStack Overflow