0

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?

3
  • the error is quite obvious or may be i didnt get the question Commented Apr 1, 2015 at 13:26
  • My-attribute is removed by my-element from my-element and added to input within my-element which has ngModel Commented Apr 1, 2015 at 13:28
  • 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 error Commented Apr 1, 2015 at 13:30

2 Answers 2

2

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',
....
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

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.