5

AngularJS 1.5では、コンポーネントから(マルチスロット)継承スコープにバインディングを渡したいと思っています - テンプレート内の参照(特定のもの、いずれの方法も問題ありません)。コンポーネント内の継承されたスコープへのバインディングの受け渡し

これは.component()から

// Component 
.component('mySelect', { 
    bind: { 
     collection: '<' 
    }, 
    transclude:{ 
     header: 'mySelectHeader', 
     item: 'mySelectItem' 
    }, 
    templateUrl: 'my-select-template', 
    controller: function(){ 
     ..... 
    } 
}); 

... 
// Component template 
<script id="my-select-template" type="text/ng-template"> 
<ol> 
    <li ng-transclude="header"> </li> 
    <li ng-transclude="item" 
     ng-click="$ctrl.select($item)" 
     ng-repeat"$item in $ctrl.collection"> 
    </li> 
</ol> 
</script> 

... 
// Example usage 
<my-select collection="[{id: 1, name: "John"}, {id: 2, name: "Erik"}, ... ]> 
    <my-select-head></my-select-head> 

    <!-- Reference to $item from ng-repeate="" in component --> 
    <my-select-item>{{$item.id}}: {{$item.name}}</my-select-item> 

</my-select> 

が可能です。この一般的なカスタム選択リストを作成するのですか? transclusionのカスタムディレクティブを使用していますか?あなたの親コンポーネントで

+1

あなたが達成したいと思っているものと本質的に逆になります。 – zeroflagL

答えて

4

あなたの子コンポーネントの私の選択項目では

を「のSelectedItem」のような変数を保持し、私の-選択は、

require: { 
    mySelect: '^mySelect' 
} 

そして、あなたのmy-で以下のようなあなたの親コンポーネントが必要ですコンポーネントのコントローラーを項目に選択し、選択した項目は今

からアクセスできるように、あなたの親コンポーネント

$onInit =() => { 
    this.mySelectedItem= this.mySelect.selectedItem; // to use it inside my-select-item component. 
}; 
select($item) { 
    this.mySelect.selectedItem = $item; // to change the selectedItem value stored in parent component 
} 

にアクセスするには

<my-select-item>{{selectedItem.id}}: {{selectedItem.name}}</my-select-item> 
+0

はい!それは、私はこれを達成する方法を考えていた!あまりにも悪いことに、それを$ onChangesライフサイクルイベントthoにフックできません。決して$ doCheckが私たちのためにそれを処理することは少なく、ちょっとちょっとちょっと汚いと感じます。 –

0

私もこの問題に遭遇し、salihの回答を基に作成しました。免責事項 - 私はこれが必ずしもあなたの問題の最良のアプローチではないと考えています。

.component('item', { 
    require: { mySelect: '^mySelect' }, 
    bind: { item: '<' } 
}) 

を、その後、あなたのテンプレートを微調整:次のようにそれは、MySelectとコンポーネント用のスタブアウトコンポーネントを作成する必要が、これはにバインドされた値を持つ項目コンポーネントは常にありますを意味します

<script id="my-select-template" type="text/ng-template"> 
<ol> 
    <li ng-transclude="header"> </li> 
    <li ng-click="$ctrl.select($item)" 
     ng-repeat"$item in $ctrl.collection"> 
     <item item="$item" ng-transclude="item"></item> 
    </li> 
</ol> 
</script> 

それ。

.component('myItemComponent', { 
    require: { 
     itemCtrl: '^item', 
    } 
    template: '<span>{{$ctrl.item.id}}: {{$ctrl.item.name}}</span>', 
    controller: function() { 
     var ctrl = this; 
     ctrl.$onInit = function() { 
      ctrl.item = ctrl.itemCtrl.item; 
     } 
    } 
}); 

とそれを使用する:今、あなたはカスタムコンポーネントに必要としてそれを使用することができます

<my-select collection="[{id: 1, name: "John"}, {id: 2, name: "Erik"}, ... ]> 
    <my-select-head></my-select-head> 

    <my-select-item> 
     <my-item-component></my-item-component> 
    </my-select-item> 
</my-select> 

私はこれを実装した後、私は実際に私の戦略を変更することを決めました。これもあなたのために働くかもしれません。代わりにtranscludeを使用して、私はすなわち、フォーマット関数に渡された:

.component('mySelect', { 
    bind: { 
     collection: '<', 
     customFormat: '&?' 
    }, 
    transclude:{ 
     header: 'mySelectHeader' 
    }, 
    templateUrl: 'my-select-template', 
    controller: function(){ 
     var ctrl = this; 
     ctrl.format = function(item) { 
      if(ctrl.customFormat) { 
       return customFormat({item: item}); 
      } else { 
       //default 
       return item; 
      } 
     } 
     ..... 
    } 
}); 

を、テンプレートには、単に使用:

<script id="my-select-template" type="text/ng-template"> 
<ol> 
    <li ng-transclude="header"> </li> 
    <li ng-click="$ctrl.select($item)" 
     ng-repeat"$item in $ctrl.collection" 
     ng-bind="::$ctrl.format($item)"> 
    </li> 
</ol> 
</script> 

は、あなたが任意のフィードバックや質問があれば私に知らせて!

関連する問題