1

Is there any particular reason why this deep watch doesn't fire?

http://plnkr.co/edit/6FxMS4RlfljBMkprZYQs?p=preview

Could it be that watch doesn't check angular attributes? Ie. those begging with $? If that's the case, is there any way to watch on validity change, and not just on the form, but on any of the inputs?

3
  • What is your goal? If you put that directive on the input, then the directive will work as intended. However, if you want a directive that can be put on a form, that will log the activity of EVERY input within it will require more work. Commented Jan 16, 2014 at 14:44
  • I also feel like you should be using the form directive to handle all of this. Commented Jan 16, 2014 at 14:47
  • the idea was to iterate thru all inputs every time a validity changes, if it's not valid, append the error message otherwise remove any previous error message.. and the problem is, that the watch doesn't fire, so I have no way of knowing the validity has changed.. and do not want to put it on every input separately.. Commented Jan 16, 2014 at 14:53

3 Answers 3

5

The solution is to watch on .$error, which works just fine. See http://plnkr.co/edit/6FxMS4RlfljBMkprZYQs?p=preview

It's basically like watching on form's valid, except that this one updates everytime any validity inside changes.

Credit goes to https://stackoverflow.com/users/490498/jonathan-rowny

Sign up to request clarification or add additional context in comments.

1 Comment

Just out of interest, is the function in your directive a type of link function? It's unspecified.
2

Maybe a bit later but i have found another way. Using:

$scope.$watchCollection

in particular you can watch the myForm variabile inside the scope using $watchColletion and update your buttons or anything you need.

$scope.$watchCollection(function () {
        if ($scope.myForm)
            return $scope.myForm;
    }, function () {
       if ($scope.myForm)
       if (($scope.myForm.$invalid == true))
              $scope.formValidityChange(true);
        else
            $scope.formValidityChange(false);
    }, true);

this will check all the variabiles that change inside the form and you will update the controller. i think u can also check what is changed by comparing the two objects maybe this can be more difficult.

Comments

0

$watch watches changes on the $scope. Since your input is not bound to the same $scope property that is being watched, your watch listener is only called once, on initialization.

To give a little better idea of how $watches, binding and $scope works, here is what your scope looks like (actually, your scope is empty, because you haven't written anything into it, but this is what it WOULD look like based on your template):

{
    shizzle: { // <--- This is the property you're watching
        $valid: false,
        whatev: { 
            valid: false
        }
    },
    whatev: "" // <--- This is the object that is changing when you type into the <input>

}

As you can see, shizzle is being watched, but doesn't change, so the watch listener is only fired once.

Here is an edited version of your plunker that binds the watcher to the input's model, and logs all changes, for demonstration:

http://plnkr.co/edit/NrE5blIbyBcsOjC2vIrk?p=preview

EDIT: If your goal is to watch the $valid attribute, which angular is setting, then you can change this line:

scope.$watch(attrs.name, function(newVal, oldVal) {
    console.log(newVal);
}, true);

to this:

scope.$watch("shizzle.$valid", function(newVal, oldVal) {
    console.log(newVal);
}, true);

2 Comments

Huh, but when I console.log forms scope after changing validity, that whatev inside shizzle does change.. $valid does anyway, which is all I need anyway, I don't need to watch on ng-model change..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.