5

在AngularJS 1.5中,我想將組件綁定傳遞到(多槽)transcluded作用域 - 用於模板中的引用(無論是特定的還是所有的 - 沒有任何一種方式是好的)。在組件中傳遞綁定到transcluded作用域

這是創建一個通用的自定義選擇列表

// 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> 

這是可能從.component()?用transclusion的自定義指令?

+1

轉換本質上與你想達到的目的相反。 – zeroflagL

回答

4

在你父組件我的,選擇保持像「將selectedItem」

在你的子組件我的選項變量,需要你的父組件像下面

require: { 
    mySelect: '^mySelect' 
} 

而在你我的 - 選擇項組件的控制器,訪問你的父組件

$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生命週期事件中。 $ doCheck可以爲我們處理的東西越少,只是覺得有點骯髒。 –

0

我遇到了這個問題,並且基於salih的回答,我提出了一個解決方案(免責聲明 - 請參閱底部:我認爲這不一定是解決問題的最佳方法)。它涉及到創建在mySelect組件使用掐滅組件,如下所示:

.component('item', { 
    require: { mySelect: '^mySelect' }, 
    bind: { 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"> 
     <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> 

讓我知道,如果您有任何意見或疑問!

相關問題