0
votes

I have an element directive and an attribute directive:

<my-element my-attribute="value"></my-element>

my-attribute is a directive which require ngModel:

    app.directive('myAttribute', [
    function() {

        var definition = {
            restrict: 'A',
            require: 'ngModel',
            link: function ($scope, $element, $attrs, ctrl) {...}
}
return definition;

my-element can be used without ng-model but the template of my-element contains input which always has ng-model. The my-attribute should be removed from my-element and added to input inside my-element. In my compile function in my-element directive I have:

var value = element.attr('my-attribute');
element.remove('my-attribute'); 
element.find('input').attr('my-attribute', value);

It works ok when attribute directive doesn't have require: 'ngModel'. But if I have ngModel required I get:

Error: [$compile:ctreq] Controller 'ngModel', required by directive 'myAttribute', can't be found!

Why? How can I fix this?

2
the error is quite obvious or may be i didnt get the questionharishr
My-attribute is removed by my-element from my-element and added to input within my-element which has ngModellatata
but even before angular replaced your directive html, it will validate if require attribute is satisfied or not... and at that point, you dont have ng-model in attributes of your directive... hence the errorharishr

2 Answers

2
votes

When you have require: 'ngModel' you'll receive an error if you don't have an ng-model attribute on that element the directive is on - that's what this directive property means. It says "give me the controller of ngModel's controller to be available as the 4th parameter in the link function.

To avoid this, if you don't always need to use it, you can add a ? sign before the ngModel and it means it's optional:

....
require: '?ngModel',
....
1
votes

If you want to remove an attribute you should use

element.removeAttr('my-attribute');

I'm not sure about your intention in the link function, but you could make the link function in myAttribute run only if there is a ng-model attribute on the element:

require: 'ngModel',
compile: function(el, attr) {
    if (attr.ngModel) {
        return function(scope, elm, attr, ngModel) {
            // link function
        }
    }
}

This is possible because angular doesn't try to find the required directives until it's going to execute the link function for that directive.