扩展Angular指令

我想对第三方指令(特别是Angular UI Bootstrap )做一些小修改。 我只是想添加到pane指令的范围:

 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 }; }]); 

但是我也想让Angular-Bootstrap跟Bower保持同步。 只要我运行bower update ,我会覆盖我的更改。

那么我该怎么把这个指令从这个bower组件分开来呢?

解决这个问题的最简单的方法可能是在您的应用程序上创build一个与第三方指令相同的指令。 这两个指令都将运行,您可以使用priority属性指定它们的运行顺序(优先级较高的运行优先级)。

这两个指令将共享范围,您可以通过指令的link方法访问和修改第三方指令的范围。

选项2:您也可以通过简单地将自己的任意命名指令放在与它相同的元素上(假定这两个指令都不使用隔离作用域)来访问第三方指令的作用域。 元素上的所有非隔离范围指令将共享范围。

进一步阅读: https //github.com/angular/angular.js/wiki/Understanding-Directives#extending-directives

注:我以前的答案是修改第三方服务,而不是指令。

TL; DR – gimme tha demo!


大演示button


使用$providedecorator()来装饰第三方的指令。

在我们的例子中,我们可以像这样扩展指令的范围:

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

首先,我们要求通过传递它的名字来连接pane指令,连接到Directive作为第一个参数,然后我们从callback参数(这是一个匹配这个名字的指令数组)中检索它。

一旦我们得到它,我们可以获得它的范围对象,并根据需要扩展它。 请注意,所有这些都必须在config块中完成。

一些笔记

  • build议只需添加一个同名的指令,然后设置其优先级。 除了没有语义( 甚至不是一个字 ,我知道…),它提出了一些问题,例如,如果第三方指令的优先级改变了怎么办?

  • JeetendraChauhan声称(我还没有testing过),这个解决scheme在版本1.13中不起作用。

虽然这不是你的问题的直接答案,但你可能想知道http://angular-ui.github.io/bootstrap/的最新版本(在master中)添加了对禁用选项卡的支持。; 这个function是通过添加: https : //github.com/angular-ui/bootstrap/commit/2b78dd16abd7e09846fa484331b5c35ece6619a2

另一种解决scheme是创build一个新的指令,在不修改原始指令的情况下扩展指令

解决scheme与修饰器解决scheme类似:

创build一个新的指令,并注入作为依赖你希望扩展的指令

 app.directive('extendedPane', function (paneDirective) { // to inject a directive as a service append "Directive" to the directive name // you will receive an array of directive configurations that match this // directive (usually only one) ordered by priority var configExtension = { scope: { disabled: '@' } } return angular.merge({}, paneDirective[0], configExtension) }); 

这样,您可以在同一个应用程序中使用原始指令和扩展版本

这里是另一种解决scheme,用于将绑定扩展到具有bindToController属性的指令。

注意:这不是在这里提供的其他解决scheme的替代scheme。 它只解决了使用bindToController设置原始指令的特定情况(其他答案中未涉及)。