扩展 AngularJs 指令

我想对第三方指令(特别是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 组件分开扩展呢?


答案 1

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

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

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

延伸阅读:https://github.com/angular/angular.js/wiki/Dev-Guide%3A-Understanding-Directives

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


答案 2

TL;DR - gimme tha demo!


     大演示按钮     
 


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

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

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

首先,我们请求通过传递其名称来修饰指令,将其作为第一个参数连接,然后从回调参数(这是与该名称匹配的指令数组)中检索它。paneDirective

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

一些注意事项

  • 有人建议简单地添加一个具有相同名称的指令,然后设置其优先级。除了不语义(我知道这甚至不是一个词......)之外,它还会带来问题,例如,如果第三方指令的优先级发生变化怎么办?

  • JeetendraChauhan声称(我还没有测试过)这个解决方案在1.13版本中不起作用。