Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$scope.watch with controller as syntax #449

Closed
jansepke opened this issue Jul 17, 2015 · 12 comments
Closed

$scope.watch with controller as syntax #449

jansepke opened this issue Jul 17, 2015 · 12 comments

Comments

@jansepke
Copy link

In your example of watching with a controller as syntax (Style Y032) you don't make it clear that you will couple the controller to its view because your snippet will only work if there is SomeController as vm in your view.

For me this is a disadvantage in using the whole controller as syntax. You could solve this with using the function notation of $scope.watch or write something about the problems using your current approach.

@johnpapa
Copy link
Owner

PR if you like

@jansepke
Copy link
Author

so do you think I should just write about the problems using controller as with $scope.$watch or should I introduce the functions notation like

$scope.$watch(function () {
    return vm.title;
}, function(current, original) {
    $log.info('vm.title was %s', original);
    $log.info('vm.title is now %s', current);
});

replacing the old example or should I compare both?

If I understand your structure I would compare both and use your avoid and recommended syntax.

@wardbell
Copy link
Contributor

Brrrr. Watching inside a controller an anti-pattern. You really don't need it in this example anyway; would be better to add change event binding (and I believe that's what you'll be doing in Ng2).

I'd prefer this discussion to be a sub-section of the "ControllerAs" which begins by urging folks to avoid watching inside a controller. Then, "if you must", I'd just go with @JanDalF version and not make too big a deal about the risks of evaluating the 'vm.title' expression. Just say: "do it this way".

@jansepke
Copy link
Author

what do you think about this preview:

controllerAs and $watch

[Style Y999] // whats the next free number?

Note: Create watches with caution as they add more load to the digest cycle. Use ngChange instead.

  • use the function notation of $scope.$watch to watch for changes

Why?: the controller could be bound to another value then vm

So if you really need to watch a value use this pattern:

  <input ng-model="vm.title"/>
  function SomeController($scope, $log) {
      var vm = this;

      $scope.$watch(function () {
          return vm.title;
      }, function(current, original) {
          $log.info('vm.title was %s', original);
          $log.info('vm.title is now %s', current);
      });
  }

@johnpapa
Copy link
Owner

johnpapa commented Aug 6, 2015

Hmmmm

It has to be clear that watching in controllers should be avoided. use ngChange instead. Or move the watch to a directive. thoughts?

Then a new rule for how to use watch with controllerAs that replaces or updates what I have in there.

@wardbell
Copy link
Contributor

wardbell commented Aug 6, 2015

Agree with you, John.

It isn't clear enough that a watch in a controller is to be avoided and that listening to the change event OR writing a directive is preferred. Should have a "why" for this advice too (why watches in controllers are bad)

The advice on how to do it if you must should be separate point and should begin with a repeat strong warning against.

THEN I'd like to see a case for why I'd do it at all. I don't see one here. Can't actually think of one. Can you?

Without such an example, I would be reluctant to include this advice at all.

Also, the "Why" in this text confused me. It's a "why" for the specific technique of avoiding dependence on the "vm" name. That's secondary to the real why, which is why you'd ever watch in a controller. It makes sense only if preceded by a "don't do it this way" example.

More work to be sure but necessary I think.

@johnpapa
Copy link
Owner

proposal anyone?

@rfeijolo
Copy link

I think that this summarizes the discussion


controllerAs $watch

[Style Y999]
  • Avoid using $scope.$watch. Use ng-change or a custom directive instead.

    Why?: Watches are harder to test and they are also bad for performance because they are evaluated in every $digest loop.

    /* avoid */
    function SomeController($scope) {
      var vm = this;
    
      $scope.$watch(function () {
          return vm.title;
      }, doSomething);
    
      function doSomething() {
      }
    }
    <!-- recommended -->
    <input type="text" ng-model="vm.title" ng-change="vm.doSomething()"/>
    /* recommended */
    function SomeController() {
        var vm = this;
        vm.doSomething = doSomething;
    
        function doSomething() {
        }
    }

@EightArmCode
Copy link

Do you document the $watch inside the directive using controllerAs? Can you recommend a link or resource?

@johnpapa
Copy link
Owner

johnpapa commented Sep 5, 2016

anyone interested in making a PR ?

@jansepke
Copy link
Author

cleanup my old issues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants