web-dev-qa-db-ja.com

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を実行するとすぐに、変更を上書きします。

このディレクティブをこのバウアーコンポーネントとは別に拡張するにはどうすればよいですか?

114
Kyle

おそらくこれを解決する最も簡単な方法は、サードパーティのディレクティブと同じ名前でアプリにディレクティブを作成することです。両方のディレクティブが実行され、priorityプロパティを使用して実行順序を指定できます(優先度の高い実行が最初に実行されます)。

2つのディレクティブはスコープを共有し、ディレクティブのlinkメソッドを介してサードパーティディレクティブのスコープにアクセスして変更できます。

オプション2:独自の任意の名前のディレクティブを同じ要素に配置するだけで、サードパーティのディレクティブのスコープにアクセスすることもできます(どちらのディレクティブも隔離を使用しないと仮定します)範囲)。 要素のすべての非分離スコープディレクティブはスコープを共有します。

さらに読む:https://github.com/angular/angular.js/wiki/Dev-Guide%3A-Understanding-Directives

注:私の以前の答えは、ディレクティブではなく、サードパーティのサービスを変更することでした。

96
Dan

TL; DR-gimme tha demo!


大きなデモボタン


$provideの-​​ decorator() を使用して、サードパーティのディレクティブを装飾します。

この場合、次のようにディレクティブのスコープを拡張できます。

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

最初に、最初の引数としてpaneと連結された名前を渡すことで、Directiveディレクティブを修飾することを要求し、次にコールバックパラメーター(その名前に一致するディレクティブの配列)から取得します。

取得したら、スコープオブジェクトを取得し、必要に応じて拡張できます。これらはすべてconfigブロックで行う必要があることに注意してください。

いくつかのメモ

  • 同じ名前のディレクティブを単純に追加し、その優先度を設定することが提案されています。セマンティックでないこと( Wordでさえない 、私は知っています...)以外に、問題を引き起こします。サードパーティのディレクティブの優先レベルが変更された場合はどうなりますか?

  • JeetendraChauhanは、このソリューションはバージョン1.13では機能しないと主張しています(ただし、テストしていません)。

60
Eliran Malka

これはあなたの質問に対する直接的な答えではありませんが、 http://angular-ui.github.io/bootstrap/ の最新バージョン(マスター)がタブを無効にするサポートを追加したことを知りたいかもしれません。この機能は次の方法で追加されました: https://github.com/angular-ui/bootstrap/commit/2b78dd16abd7e09846fa484331b5c35ece6619a2

元のディレクティブを変更せずにそれを拡張する新しいディレクティブを作成する別のソリューション

ソリューションは、デコレータソリューションに似ています。

新しいディレクティブを作成し、拡張したいディレクティブを依存関係として注入します

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

このようにして、同じアプリで元のディレクティブと拡張バージョンを使用できます

6
kidroca

別のソリューションがありますbindToControllerプロパティを持つディレクティブにバインディングを拡張する異なるシナリオの場合。

注:これは、ここで提供された他のソリューションに代わるものではありません。元のディレクティブがbindToControllerで設定された特定のケース(他の回答ではカバーされていません)のみを解決します。

1
gilad mayani