latata
latata

Reputation: 1723

How to remove attribute directives from element directive in AngularJS?

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?

Upvotes: 0

Views: 10089

Answers (2)

eladcon
eladcon

Reputation: 5825

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.

Upvotes: 1

Omri Aharon
Omri Aharon

Reputation: 17064

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',
....

Upvotes: 2

Related Questions