2016-07-13 6 views
2

要するに次の質問があります:AngularJSは外部コントローラを渡して使用します

コントローラーを正しく渡して、transcludeブロックで使用します。

私が望むのは、指示者のユーザーに、transcludeブロック内の特定のコントローラを使用する機会を与えることです。異なるディレクティブの用途に共通ではない特定のアクションを実装する目的。

私はコントローラとして属性を送信し、何らかの形でそのフィールドをリンク関数のスコープに追加することはできますが、正しい方法はわかりません。

私の現在の試行は次です。 ベースHTML:

<mylist items="list" ctrl="internalCtrl1"> 
     <li> 
     {{element}} <a ng-click="showAbc()">ShowAbc</a> 
     </li> 
    </mylist> 
    <h3>List2</h3> 
    <mylist items="list" ctrl="internalCtrl2"> 
     <li> 
      {{element}} <a ng-click="showXyz()">ShowXyz</a> 
     </li> 
    </mylist> 

指令:

<div> 
    <p>Cool list</p> 
    <!--<ul ng-controller="ctrl">--> 
    <ul> 
    <ng-transclude></ng-transclude> 
    </ul> 
<div> 

ディレクティブスクリプト:

......... 
    scope: { 
     ctrl: "=", 
     items: '=' 
    }, 
    controller: function($scope){ 
     //some common stuff 
    }, 
    link: function($scope, $element, $attrs, controller, $transclude) { 
     $scope.$watch("items", function(items) { 

     var el = $element.find("ul"); 
     el.empty(); 

     if(items) 
      items.forEach(function(item) { 
      var childScope = $scope.$new(); 
      childScope.element = item; 

      $transclude(childScope, function(content) { 
       el.append(content); 
      }); 

      }); 

     }); 
    } 

全コード:https://plnkr.co/edit/kPSu9s9xpHJdACFzofdP

非常に感謝すべてのヘルプ。

Upd。私は今2つの問題を抱えて:私はディレクティブに渡されたコントローラを使用する場合

  • を - 私は、エラーに「Ctrl」を得た私はディレクティブで固定コントローラを使用する場合 ない機能
  • ある - コントロールに アクセス決してありませんtranscludeブロックからの機能
+1

トランスクルードコンテンツが、それはなぜあなたはこれを保持している要素に 'NG-controller'を追加しないだろう、自分のコントローラの必要がある場合コンテンツ?例えば'

some content that needs insideController
' – Claies

+0

私はこの内部コントローラが外部から送信されてほしいです。しかし、私が正確なコントローラを使用しても、ng-clickは動作しません。実際には2つの問題があります。 – johngull

+1

は 'scope'にあり、' = 'は双方向バインド*データ*交換です。このように関数を渡すことはできません。もしあなたが本当に***このようにしたいなら、 'ctrl'を関数として渡すには'& 'が必要です。しかし、あなたがこれをやる理由はまだ分かりませんし、あなたが完全に説明していない問題の回避策について助けを求めているように感じていますし、説明した方が問題を解決する良い方法があるかもしれませんより完全に。 – Claies

答えて

1

私は、これはあなたが欲しいものだと思う...

.directive('mylist', function($controller){ 
    return { 
    restrict: 'E', 
    transclude: true, 
    replace: true, 
    templateUrl: 'mylist.html', 
    scope: { 
     ctrl: "@", 
     items: '=' 
    }, 
    controller: function($scope){ 
     //some common stuff 
    }, 
    link: function($scope, $element, $attrs, controller, $transclude) { 
     $scope.$watch("items", function(items) { 

     var el = $element.find("ul"); 
     el.empty(); 
     if(items) 
      items.forEach(function(item) { 
      var childScope = $scope.$new(); 
      childScope.element = item; 
      var theCtrl = $controller($scope.ctrl, { 
       $scope: childScope 
      }); 

      $transclude(childScope, function(content) { 
       el.append(content); 
      }); 

      }); 

     }); 
    } 
    }; 
}) 

https://plnkr.co/edit/7CFcOAB8HjeGARtq3K1t?p=preview

通知は、私はあなたが本当にただのコントローラの名前をしたいので、「@」に結合し、あなたのCtrlキーを変更しました。あなたのリンクで$ controllerオブジェクトを使ってコントローラをインスタンス化し、新しく作成した子スコープを渡します。それはインスタンス化中にコントローラのメソッドをchildScopeに追加します。

編集:あなたの意図に基づいて

、あなたは異なっこれにアプローチすることができます。おそらく、あなたの "スマート"テーブルを複数のディレクティブに分割する必要があります。 1つはルートにすることができ、1つは行にすることができます。行は'&'などon-select="myCtrl.selectItem(item)"を機能バインディングを持つことができ、ユーザーがこのような何かを行うことができます。

<smart-table items="items" on-paginate="paginateHandler()"> 
    <smart-table-row on-select="selectHandler(item)" ng-repeat="item in items"></smart-table-row> 
</smart-table> 
+0

すべての要素は同じコントローラインスタンスを共有しますか? – johngull

+0

このコントローラをul要素に接続することは可能ですか? – johngull

+0

$ new()を実行しているので、同じスコープを共有することはありません。私はそれがあなたが望んだものだと思った。実際には、アイテムをそれぞれの要素プロパティに設定しているため、別々のスコープが必要です。同じコントローラインスタンスを共有し、実際に名前の代わりにコントローラ自体を渡したい場合は、ControllerAs構文を使用するようにしてください。 – Zach

関連する問題