Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS - Access child directive controller

How to access the child directive controllers? Specifically, I need to access all ngModelController(s) which are present inside a parent directive. Example:

<parent-directive>
  <input type="text" ng-model="model1"/>
  <input type="text" ng-model="model2"/>
</parent-directive>

So, is there a way for "parentDirective" to get access to the ngModelControllers for "model1" and "model2"?

like image 683
Christian Avatar asked Jan 06 '15 22:01

Christian


People also ask

How to get child scope in AngularJS?

Scopes in AngularJS use prototypal inheritance, when looking up a property in a child scope the interpreter will look up the prototype chain starting from the child and continue to the parents until it finds the property, not the other way around. In a nutshell: You cannot access child scopes from a parent scope.

What is attrs in AngularJS?

Using attrs you are able to access the attributes defined in your html tag like <fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true">

What is restrict option in directive?

Note: When you create a directive, it is restricted to attribute and elements only by default. In order to create directives that are triggered by class name, you need to use the restrict option. The restrict option is typically set to: 'A' - only matches attribute name. 'E' - only matches element name.


1 Answers

Update

jqLite extras methods also has a controller method to retrieve the specific controller associated to the element. So you can query for the ng-models and get the controller name as angular.element(el).controller('ngModel') as well.

controller(name) - retrieves the controller of the current element or its parent. By default retrieves controller associated with the ngController directive. If name is provided as camelCase directive name, then the controller for this directive will be retrieved (e.g. 'ngModel').


angular also places the controller associated with an element on its data. Similarly ngModel controller instance associated with the directive is accessibly via $ngModelController. So you could actually access it and use the ngModel instance to do whatever you are doing. However this is completely a non standard way of doing it, because $ngModelController is undocumented and there is no guarantee the implementation will not change in future versions.

An example implementation:

.directive('parentDirective', function($timeout){
  return{
    restrict:'E',
    link:function(scope, elm){
      /*Get the elements with the attribute ng-model, in your case this could just be elm.children()*/
      var elms = [].slice.call(elm[0].querySelectorAll('[ng-model]'), 0);

      /*get the ngModelControllerArray*/
      var controllers = elms.map(function(el){ 
          return angular.element(el).controller('ngModel');
          //return angular.element(el).data('$ngModelController');
      });

       /*As a sample implementation i am registering a view value listener for these controller instances*/
       controllers.forEach(function(ngModel){
         ngModel.$viewChangeListeners.push(logViewChange.bind(null, ngModel));
       });

       function logViewChange(ngModel){
           console.log(ngModel.$name, ngModel.$viewValue);
       }
    }
  }
});

Plnkr

like image 144
PSL Avatar answered Sep 19 '22 17:09

PSL