Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending AngularJs Directive

I'd like to make a minor modification to a 3rd party directive (specifically Angular UI Bootstrap). I simply want to add to the scope of the pane directive:

angular.module('ui.bootstrap.tabs', []) .controller('TabsController', ['$scope', '$element', function($scope, $element) {   // various methods }]) .directive('tabs', function() {   return {     // etc...   }; }) .directive('pane', ['$parse', function($parse) {   return {     require: '^tabs',     restrict: 'EA',     transclude: true,     scope:{       heading:'@',       disabled:'@' // <- ADDED SCOPE PROPERTY HERE     },     link: function(scope, element, attrs, tabsCtrl) {       // link function     },     templateUrl: 'template/tabs/pane.html',     replace: true   }; }]); 

But I also want to keep Angular-Bootstrap up to date with Bower. As soon as I run bower update, I'll overwrite my changes.

So how do I go about extending this directive separately from this bower component?

like image 823
Kyle Cureau Avatar asked Jun 09 '13 00:06

Kyle Cureau


People also ask

Can we extend directive in angular?

Angular Directives are great, but sadly underused. Directives are what the Open-Closed Principle is about. The component is closed for modifications, but a directive allows you to extend the component without changing the internals.

Which component of AngularJS helps us extend HTML elements?

AngularJS Directives AngularJS lets you extend HTML with new attributes called Directives. AngularJS has a suite of in-built directives which adds features to your web app. AngularJS also lets you state your own directives. AngularJS directives are HTML attributes with an ng prefix.

What is an AngularJS directive?

Directives are markers on the DOM element which tell AngularJS to attach a specified behavior to that DOM element or even transform the DOM element with its children. Simple AngularJS allows extending HTML with new attributes called Directives.

What is restrict in AngularJS directive?

The restrict option is typically set to: 'A' - only matches attribute name. 'E' - only matches element name. 'C' - only matches class name. 'M' - only matches comment.


2 Answers

Probably the simplest way to solve this is to create a directive on your app with the same name as the third party directive. Both directives will run and you can specify their run order using the priority property (higher priority runs first).

The two directives will share scope and you can access and modify the scope of the third party directive via your directive's link method.

Option 2: You can also access a third party directive's scope by simply putting your own arbitrarily named directive on the same element with it (assuming neither directive uses isolate scope). All non-isolate scope directives on an element will share scope.

Further Reading: https://github.com/angular/angular.js/wiki/Dev-Guide%3A-Understanding-Directives

Note: My previous answer was for modifying a third party service, not a directive.

like image 82
Dan Avatar answered Oct 12 '22 01:10

Dan


TL;DR - gimme tha demo!


     Big Demo Button     
 


Use $provide's decorator() to, well, decorate the third party's directive.

In our case, we can extend the directive's scope like so:

app.config(function($provide) {     $provide.decorator('paneDirective', function($delegate) {         var directive = $delegate[0];         angular.extend(directive.scope, {             disabled:'@'         });         return $delegate;     }); }); 

First, we request to decorate the pane directive by passing its name, concatenated with Directive as the first argument, then we retrieve it from the callback parameter (which is an array of directives matching that name).

Once we got it, we can obtain its scope object and extend it as needed. Notice that all of this has to be done in the config block.

Some notes

  • It has been suggested to simply add a directive with the same name, then set its priority level. Aside from being unsemantic (which's not even a word, I know…), it poses issues, e.g. what if the third-party directive's priority level changes?

  • JeetendraChauhan has claimed (I haven't tested it though) that this solution will not work in version 1.13.

like image 34
Eliran Malka Avatar answered Oct 12 '22 01:10

Eliran Malka