wazzaday
wazzaday

Reputation: 9664

Watch ngModel value change from directive on parent element

I have a directive which watches for change in an input field

directive('autocomplete', function(){
    return {
        link: function(scope, element, attrs){
            scope.$watch(attrs.ngModel, function(){
                console.log('change');
            });
        }
    };
});

This works fine on the following element

<input type='text' ng-model='searchTerm' autocomplete>

But what if I was to put my directive on an ancestor element, like this:

<div autocomplete>
    <input type='text' ng-model='searchTerm'>
</div>

How could I still watch the input for change then?

Upvotes: 0

Views: 494

Answers (1)

hon2a
hon2a

Reputation: 7214

Simply put: you could, but you shouldn't.

First, the ngModel directive has a controller. Its $viewChangeListeners property is probably what you'd really want to use (as your "autocomplete" directive is probably going to be looking out just for view value changes). You can just push your change listener into that array.

Second (and more to the point), you shouldn't direct that kind of functionality from the ancestor element only. If you wish to interact with ngModel, you'd better put your directive right on the element using it or its descendant (not an option with an <input>). This doesn't stop you from putting some common logic on an ancestor and interacting with that ancestor (much like ngModel interacts with ngForm).


If you don't care about shoulds and shouldn'ts, you can always either

  1. put a name on your input and get the ngModelController from the ngForm (if your directive is under it), or
  2. find the <input> and get the ngModelController using angular.element(...).controller('ngModel').

Upvotes: 1

Related Questions