javascript - Using $scope.$watch when using `this` scope in controller - Stack Overflow

I have a controller in my Angular app:(function (angular) {function MyController() {this.name = 'D

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744085657a4556123.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信