Angularディレクティブの拡張


114

サードパーティのディレクティブ(特に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とすぐに、変更を上書きします。

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


2
クリーンな方法は、使用することです$provide.decorator()、下記の私の答えを参照してください。
Eliran Malka 14

回答:


96

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

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

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

詳細情報: https : //github.com/angular/angular.js/wiki/Dev-Guide%3A-Understanding-Directives

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


3
@ sh0berのおかげで、これはまさに私が必要とするものです。そして、あなたの以前の答えも私を助けてくれました、re:サードパーティのサービス。
カイル

ねえ、この答えは本当に良いですが、ディレクティブの「優先度」プロパティに関するドキュメントは見つかりません。私が見つけたのは、「あなたはそれを使うことができる」と言っている宣伝文句だけでしたが、実際の例は見つかりませんでした。
シエル14

2
@CielディレクティブAPI情報はどうやらここ$compileドキュメントに移動されまし
Dan

60

TL; DR-gimme tha demo!


     Big 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れた名前を渡してディレクティブを装飾するように要求し、次にコールバックパラメーター(その名前に一致するディレクティブの配列)からディレクティブを取得します。

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

いくつかのメモ

  • 同じ名前のディレクティブを追加してから、その優先度レベルを設定することが提案されています。非セマンティックであるだけでなく(言葉はありません、私は知っています…)、問題を引き起こします。たとえば、サードパーティのディレクティブの優先度レベルが変更された場合はどうなりますか?

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


1
@ sh0berの答えを試してみることをお勧めします(イベントを発行するためだけに別のディレクティブを作成します)。
Eliran Malka 14

2
(素晴らしい作品)この回答についての簡単なメモ、「paneDirective」の「指令」は目的を持っている;-)それはそれを考え出す前に、私はしばらく時間がかかった:stackoverflow.com/questions/19409017/...を、受け入れ見ます回答。
ロイミルダー、2015年

2
こんにちは@EliranMalka私のプランカーをチェックしてくださいplnkr.co/edit/0mvQjHYjQCFS6joYJdwK これが誰かの助けになることを願っています
Jeetendra Chauhan

1
へのリンクdecorator()が壊れている(docs.angularjs.org/api/auto/service/$provide#decoratorに更新されています
Chris Brown

1
@EliranMalkaはい、bindToControllerv1.3で導入されました。ただし、これは代替ソリューションとは見なされないことに注意してください。これは、元のディレクティブがbindToControllerプロパティを使用して設定された特定の場合にのみ当てはまります。良い考えです。これを回答として投稿します:)
gilad mayani

8

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


ヘッドアップのための+1。知っておくと良い。私はbowerのangular-bootstrapとangular-uiのbootstrapコンポーネントが同期していないと思います。
カイル

6

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

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

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

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

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


2
これは素晴らしいです。自分の変数で分離スコープディレクティブを拡張するために必要なものだけです。angular.extendはオブジェクトをディープコピーしないことがわかったので、これにより、paneDirectiveのスコープオブジェクトがこのオブジェクトに置き換えられます。別の方法は、PaneDirectiveからの元のスコープを維持し、ここで定義された変数を追加/マージするangular.mergeです。
mathewguest 2017

1
はい、angular.merge使用されるべき
でし

1

bindToControllerプロパティを持つディレクティブにバインディングを拡張する別のシナリオの別のソリューション次に示します。

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.