2017-08-21 10 views
1

2つのカスタムディレクティブmy-tileとmy-tile-itemを作成しようとしています。カスタムディレクティブのコントローラはng-repeatで動作しませんか?

"my-tile"は、データ配列の引数を受け入れるメインディレクティブです。

"my-tile-item"は、 "my-tile"内の個々のタイルを表します。

しかし、my-tile-itemコントローラのbtnOkClick()メソッドは機能しません。

コード:

https://codepen.io/anon/pen/zdWgVG

HTML:

<div my-tile tiles="mainCtrl.tiles"></div> 

私のタイルテンプレート:

<script type="text/ng-template" id="myTile.html"> 
    <div my-tile-item ng-repeat="tileItem in myTileCtrl.tiles" class="my-tile"> 
     <div>{{tileItem.id}}</div> 
     <button ng-click="myTileItemCtrl.btnOKClick()">OK</button> 
    </div> 

</script> 

私のタイトルディレクティブ:

angular.module('app').directive('myTile', 
     [ 
      myTile 
     ]); 


    function myTile() { 
     return { 
      restrict: 'AE', 
      scope: { 
      tiles: '=' 
      }, 

      controller: ['$scope', MyTileController], 
      controllerAs: 'myTileCtrl', 


      templateUrl: 'myTile.html', 

      link: function (scope, iElement, iAttrs) { 
       console.log('abc'); 
      } 
     }; 


     function MyTileController($scope) { 
      var ctrl = this; 
      ctrl.tiles = $scope.tiles; 
     } 

    } 

私のタイル項目ディレクティブ:

angular.module('app').directive('myTileItem', 
     [ 
      myTileItem 
     ]); 


    function myTileItem() { 
     return { 
      restrict: 'AE', 
      scope: { 

      }, 

      controller : ['$scope', MyTileItemController], 
      controllerAs : 'myTileItemCtrl', 

      link: function (scope, iElement, iAttrs) { 

      } 
     }; 


     function MyTileItemController($scope) { 
      var ctrl = this; 

      ctrl.btnOKClick = function() { 
       alert('OK Clicked'); // ********* does NOT work ************* 
      } 
     } 


    } 
+0

解決策が見つかりませんでしたが、問題の一部はこれです:あなたの 'ng-click'は決して考慮されません。私は 'onclick = "console.log(' test '); myTileItemCtrl.btnOKClick()" 'を実行している間、' ng-click = "console.log(' test '); myTileItemCtrl.btnOKClick()少なくともログ "テスト"を表示します(ただし、関数は呼び出されていないようですが、エラーはありません) – Kaddath

答えて

2

期待どおりに動作しています。 my-tile-itemディレクティブは独自のコントローラを持つ独自の独立スコープを持っているため、ディレクティブスコープはその要素に適用されます。ディレクティブのスコープは、ディレクティブが独自のtemplateまたはtranscluded contentを持つときに、要素でコンパイルされます。ここでmy-title-itemディレクティブにはtemplateがありません。そのため、ディレクティブはホストされている要素のディレクティブスコープには適用されません。

問題を解決するには、ディレクティブから内部テンプレートを生成した後に、myTileItemCtrlスコープを要素で使用できるようにします。次に、範囲をmy-title-itemmy-tileディレクティブに渡すことを検討できます。

<script type="text/ng-template" id="myTile.html"> 
    <div ng-repeat="tileItem in myTileCtrl.tiles" class="my-tile"> 
     <my-tile-item item="tileItem"></my-tile-item> 
    </div> 
</script> 

私の項目指令

function myTileItem() { 
    return { 
     restrict: 'AE', 
     scope: { 
      item: '<' 
     }, 
     template: ` 
      <div>{{item.id}}</div> 
      <button ng-click="myTileItemCtrl.btnOKClick()">OK</button> 
     `, 
     //... 
    } 
} 

Forked Codepen

テンプレート構造上に持つことにより、親は子としてのみ結合し、受け入れメイン責任のためにほとんど責任があるどこにもSmart and Dumb Component Patternを達成それを目に見えるようにする。

0
(function() { 
    'use strict'; 

    angular.module('app').directive('myTileItem', 
     [ 
      myTileItem 
     ]); 


    function myTileItem() { 
     return { 
      restrict: 'AE', 
      link: function (scope, iElement, iAttrs) { 
       scope.btnOKClick = function() { 
       alert('OK Clicked'); 
      } 
      } 
     }; 
    } 
})(); 

tileItemディレクティブの機能をリンクしてもスコープを削除するbtnOnClickを移動:{}それは作業を開始します。そして変更する<button ng-click="mytileItemCtrl.btnOKClick()">OK</button><button ng-click="btnOKClick()">OK</button>

0

問題はほとんどありません。

私はあなたのcodepenを変更した今では働いています:https://codepen.io/anon/pen/jLxNvE

まず間違った修正プログラムは、単にあなたの商品ディレクティブのブロックscopeを削除し、あなたの商品ディレクティブで分離された範囲を削除することができます。 このようにして、あなたのitemディレクティブは親のスコープにアクセスし、そのスコープをオーバーライドして(あなたの関数として)新しいプロパティを追加することができます。

しかし、これは間違った解決策です。

アイテムディレクティブ

で分離された範囲を削除せずにあなたがあなたの商品ディレクティブのテンプレートを定義していない最適なアプローチを次に示します。スコープを分離すると、そのディレクティブのテンプレートでのみ、親のスコープを参照せずにアクセスできるようになるため、達成しようとしているテンプレートを追加する必要があります。対応するテンプレートがない場合、その関数をそこで呼び出すことはできません。

次に、これらのケースで最も適切なことは、項目ディレクティブ定義内にスコープパラメータを指定する必要があります。これは実際には項目です(私は双方向データバインディングで行いましたが、必要に応じてバインディングを変更してください)。

このようにすべてうまく動作します。

これは意味があると思います。

関連する問題