1

Is there a standard way to create new Angular directives by extending existing directives?

Specifically I'd like to customize angular-contenteditable to allow more control over editing options, like preventing newlines:

<h1 my-custom-content-editable prevent-newlines="true">Hello, world!</h1>

Where the implementation is something like:

app.directive("myCustomContentEditable", function() {
    return {
        link: function($scope, elem, attrs) {
            angular.element(elem).on("keydown", function($event) {
                if (attrs.preventNewlines && $event.keyCode == 13)
                    $event.preventDefault();
            });
        },

    };
})

What would be the best way to extend the contenteditable directive in my custom directive?

Note that I do know that I can combine the directives at the markup level — <h1 contenteditable my-custom-content-editable>…</h1> — but I'd like to know specifically how to create a single directive that extends another.

David Wolever
  • 148,955
  • 89
  • 346
  • 502

1 Answers1

0

You don't subclass/extend directives, you can just combine them in line as in your example.

another example:

<input ng-init="myModel = 'stuff'" ng-change="somethingElse()" ng-model="myModel" />

Basically, directives do not allow inheritance. You can simply take the original code of whatever directive there is and modify it or combine directives to achieve the functionality you're looking for.

There are ways to hack at 'extending' a directive though... but this consists of using require, which I don't feel is quite the same. http://thaiat.github.io/blog/2014/03/10/extending-an-existing-directive-in-angularjs/

SoluableNonagon
  • 11,541
  • 11
  • 53
  • 98
  • Useful answers lie here: http://stackoverflow.com/questions/17005122/extending-angular-directive – SoluableNonagon Dec 01 '14 at 21:50
  • Why doesn't one subclass/extend/compose directives? – David Wolever Dec 01 '14 at 21:57
  • I'm not sure what you mean by compose, but subclass/extend refer to inheritance, right? I believe because the reason is because angular doesn't support such functionality. You can define directives of your own and you can override directives, but to the best of my knowledge, you can't use the prototypical inheritance model in JS to extend existing directives. Also, combining multiple directives like in my example above will generally achieve the results you are looking for. – SoluableNonagon Dec 01 '14 at 22:21
  • By "compose" I simply mean "programmatically use together" — let one directive use functionality defined in another without requiring any changes to the HTML. And it seems a bit strange that "it's not done" because all the pieces are there, it's just not clear how to plug them together (ex, to take an element and apply a directive to it). – David Wolever Dec 01 '14 at 22:36
  • Oh, in that case you should just use the link I provided in the answer, it pretty much addresses your concerns: http://thaiat.github.io/blog/2014/03/10/extending-an-existing-directive-in-angularjs/ – SoluableNonagon Dec 01 '14 at 22:38
  • That *also* depends on modifying the HTML to change the directive's behavior. I want *one* directive — `` — which can then use the `` directive or whatever else it wants internally. – David Wolever Dec 01 '14 at 22:44