Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Feature Request: Programmatically add directives to another directive's elements before they get compiled. #6950

Closed
@trusktr

Description

@trusktr

I ran into an issue. So far as I know, Angular doesn't have a mechanism by which to address it easily.

http://ngmodules.org has some awesome modules. They are really easy to use, but if they don't expose any events to you, then you're out of luck if you don't want to actually modify the 3rd party module's source code.

What if Angular had an easy way to attach directives to the element of another directive programmatically (before it and any sub-templates get compiled) so that one could use third party directives and not worry if they've exposed any useful features like like event handling mechanism (e.g. they don't use ngClick on any elements)?

For example, here's an example:

Suppose we use someone's awesomeDirective.

<div data-awesome-directive="awesome.data"></div>

This nice directive generates some type of awesome HTML widget with HTML that is defined in the 3rd party source code, perhaps a twitter feed, a profile badge, or something else awesome, but the author of the directive did not include any way to handle click events, etc!

We could step away from Angular, and use jQuery to make a click handler like

$("#awesomeWidget").on("click", function() {/* ... */});

but we don't want to leave the world of Angular awesomeness!

Perhaps, a new addition to the Module.directive API can be added to Angular so one can add a directive to any other directive's elements, like so:

angular.element(document).ready(function() {

    // create your app with a dependency on a 3rd party module.
    var myApp = angular.module("myApp", ["awesomeModuleContainingAwesomeDirective"]);

    // the 3rd party module contains an awesomeDirective.

    // create a custom directive:
    myApp.directive("customDirective", function() {
            return { // set up directive properties like normal.
                restrict: "A",
                scope: {/* ... */},
                // etc...
            };
        });

    // attach the custom directive to the elements of another directive:
    myApp.directive("awesomeDirective") // get the directive.
        .attachDirective(".elements", "customDirective");

    // the first argument to attachDirective() is a standard jQuery selector.
    // internally, Angular would use jQuery's .find(".element")

    // add an already-existing directive  to the elements of another directive:
    var awesomeDirective = myApp.directive("awesomeDirective"); // gets the directive.
    awesomeDirective.attachDirective(".otherElements", "ngCloak");

    // use a third argument for directives that accept an attribute expression:
    awesomeDirective.attachDirective("#oneElement", "ngClick", "count = count + 1");

    angular.bootstrap(document, ["myApp"]);

    /*
     * This would be absolutely pure awesome.
     */
});

This would be a nice way to extend directives that you are using in your app... But what if you want to attach directives to only specific instances of another directive? Then:

    myApp.directive("awesomeDirective") // gets the directive.
        .attachDirective([".rootElements", ".elements"], 'ngClick', "count = count + 1");
    // ^ still no more than 3 arguments

The first argument in this case is an array. The first element in the array tells Angular that we wish to attach our directive to elements matching the awesomeDirective only if those elements are .rootElements. All .rootElements that match the awesomeDirective will then have the ngClick directive applied to sub elements of the class elements using jQuery's .find('.elements').

Angular could benefit from something like this! And it would not only be useful for event handling that 3rd party modules haven't exposed, but for augmenting 3rd party directives with all sorts of other functionality.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions