Passing a binding to transcluded scope in component
In your parent component my-select keep a variable like "selectedItem"
In your child component my-select-item, require your parent component like below
require: { mySelect: '^mySelect'}
And in your my-select-item component's controller, to access your parent component
$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 }
So that the selected item is now accessible from
<my-select-item>{{selectedItem.id}}: {{selectedItem.name}}</my-select-item>
I ran into this problem as well, and building upon salih's answer, I came up with a solution (disclaimer--see bottom: I don't think this is necessarily the best approach to your problem). it involves creating a stubbed out component for use in the mySelect component, as follows:
.component('item', { require: { mySelect: '^mySelect' }, bind: { item: '<' }})
then, tweaking your template:
<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>
this will mean there's always an item component with the value bound to it. now, you can use it as a require in a custom component:
.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; } }});
and to use it:
<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>
after I implemented this, I actually decided to change my strategy; this might work for you as well. instead of using a transclude, I passed in a formatting function, i.e.:
.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; } } ..... }});
then in the template, just use:
<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>
let me know if you have any feedback or questions!