Unable to require directive in AngularJS 1.5 component
Asked Answered
T

1

11

I've created a directive which works perfectly fine. Now after bumping angular to 1.5.0, I figured this directive is a typical example of what could be written using the new .component() notation.

For some reason, the require property no longer seems to work.

The following is a simplified example:

angular.module('myApp', [])

.component('mirror', {
  template: '<p>{{$ctrl.modelValue}}</p>',
  require: ['ngModel'],
  controller: function() {
    var vm = this;
    var ngModel = vm.ngModel;
    
    ngModel.$viewChangeListeners.push(onChange);
    ngModel.$render = onChange;

    function onChange() {
      vm.modelValue = ngModel.$modelValue;
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="myApp">
  <input ng-model="someModel"/>
  <mirror ng-model="someModel"></mirror>
</div>

I also tried using require as a simple string:

...
require: 'ngModel'
...

and as an object:

...
require: {
  ngModel: 'ngModel'
}
...

I've looked at the docs for $compile and component, but I can't seem to get it to work.

How can I require other directive controllers in an AngularJS 1.5 component?

Tranquilize answered 10/2, 2016 at 9:48 Comment(0)
C
20

In Angular 1.5's component syntax, you don't have access to the required controllers until the component's $onInit lifecycle method is called. So you need to move your initialisation into there, here's a working version of your snippet where I added the $onInit function.

angular.module('myApp', [])

.component('mirror', {
  template: '<p>{{$ctrl.modelValue}}</p>',
  require: {
    ngModel: 'ngModel',
  },
  controller: function() {
    var vm = this;
    
    vm.$onInit = function() {
      var ngModel = vm.ngModel;
      ngModel.$viewChangeListeners.push(onChange);
      ngModel.$render = onChange;
    };
    
    function onChange() {
      vm.modelValue = vm.ngModel.$modelValue;
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
<div ng-app="myApp">
  <input ng-model="someModel"/>
  <mirror ng-model="someModel"></mirror>
</div>
Cordiality answered 8/4, 2016 at 18:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.