2015-10-19 17 views
7

子ディレクティブのlink関数で親のdirectiveコントローラをどのように取得できるか分かっています。
しかし、私はlink関数(と一緒に$scope)を使用することを避け、すべてのコードを指示のcontrollerの下に置いてください。子ディレクティブのコントローラ(リンク関数ではない)の角度取得親ディレクティブのコントローラ

angular.directive('parent', function(){ 
    return { 
     templateUrl: '/parent.html', 
     scope: true, 
     bindToController: true, 
     controllerAs: 'parentCtrl', 
     controller: function(){ 
      this.coolFunction = function(){ 
       console.log('cool'); 
      } 
     } 
    } 
}); 

angular.directive('child', function(){ 
    return { 
     templateUrl: '/child.html', 
     require: '^parent', 
     scope: true, 
     bindToController: true, 
     controllerAs: 'childCtrl', 
     controller: function() { 
      // I want to run coolFunction here. 
      // How do I do it? 
     } 
    } 
}); 

ご協力いただきましてありがとうございます。

+0

Uは、リンクを使用しないようにしたいですか?どうして? –

+0

私はAngular2に親しみやすい方法でコードを書いています。 – Dmitry

+0

@Dmitryコントローラーとjqliteに固執すると(正しい答えが示唆されているように)、あなたのコードはAngular 2に敵対的になります(これは友好的です)。 – estus

答えて

1

あなたは、コントローラに「$の要素」を注入し、同様に親コントローラにアクセスすることができました - それは、特定の名前が必要ですので、これは「任意の」親コントローラにアクセスするための最も透明な方法ではないかもしれない

controller: ($element) -> 
    var parentCtrl = $element.parent().controller('parent'); 
    parentCtrl.coolFunction(); 
    //.......... 
    //.......... 

この指令はjqliteであり、純粋なAngularではありません。角度は、コントローラを取得するために「.parent」を必要としないことを考え出すため@Dmitryにありがとう:How to access parent directive's controller by requiring it recursively?

EDIT -

が便利なこのスレッドを発見しました。更新されたコード -

controller: ($element) -> 
    var parentCtrl = $element.controller('parent'); 
    parentCtrl.coolFunction(); 
    //.......... 
+0

が目的の機能に近づいています。子供が親の直接の子ではないかもしれないので、私が満足していないのは '$ element.parent()'部分ですが、その代わりに深いカップルレベルかもしれません。私は何らかの形で「親」の属性を再帰的にチェックすることができると思います – Dmitry

+0

@Dmitry - 私は「親」参照も使用するファンではありません。私はよりエレガントな方法があることを願っています。 – FrailWords

+0

私はあなたの助けに感謝します。確かに私は正しい方向に見せてくれました。 [Angularのソースコード](https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L2005-L2042)を調べたところ、 '.parent'を呼び出す必要はないようです。私は実際にそれを試して、それは '.parent'なしで働いた。あなたの答えを更新すれば、私はそれを合格とマークします。 – Dmitry

4

そのための適切なパターンが

app.directive('child', function(){ 
    return { 
     templateUrl: '/child.html', 
     require: ['child', '^parent'], 
     scope: true, 
     bindToController: true, 
     controllerAs: 'childCtrl', 
     controller: function() { 
      this.coolFunction = function() { 
       this._parent.coolFunction(); 
      } 
     }, 
     link: function (scope, element, attrs, ctrls) { 
      var childCtrl = ctrls[0]; 
      var parentCtrl = ctrls[1]; 
      childCtrl._parent = parentCtrl; 
     } 
    } 
}); 

だろう悪い事は_parentcontrollerAsでスコープにさらされていることですが、それはほとんど問題になりません。

linkを一緒に接着するまで、子コントローラの親コントローラにアクセスすることはできません。子メソッドで親コントローラを使用している限り、これはうまくいきます。

コントローラでは、モデルを表示するためのメソッドと初期プロパティが用意されています(コントローラーではよりクリーンです)。

$scopelinkの両方は、Angular 1.xでの目的があり、最新のコミュニティ開発でも不可欠です。正当な理由がない場合にそれらをバニシングすることは、過度のものであり、悪い設計ソリューションにつながる可能性があります。コード内に「リンク」と「範囲」の単語がないと、アプリを2.xに移植しやすくなります。角2を学び、1.xのための適切な習慣を開発することはできますが。

0

See hereまたはhere

  1. var parentForm = $element.inheritedData('$formController') || ....
  2. var parentForm = $element.controller('form')