将绑定传递给组件中的transcluded范围

时间:2016-09-19 13:46:38

标签: angularjs angularjs-directive angularjs-scope web-component transclusion

在AngularJS 1.5中,我想将一个绑定从一个组件传递到(多槽)转换范围 - 用于模板中的引用(在一个特定的或全部的中 - 没有一种方法可以正常)。

这是用于创建通用自定义选择列表

// 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的自定义指令?

2 个答案:

答案 0 :(得分:5)

在您的父组件中,my-select保留一个类似&#34; selectedItem&#34;

的变量

在您的子组件my-select-item中,需要您的父组件,如下所示

require: {
  mySelect: '^mySelect'
}

在my-select-item组件的控制器中,访问您的父组件

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

答案 1 :(得分: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>
在我实施之后,我实际上决定改变策略;这对你也有用。我没有使用转换,而是传递了格式化函数,即:

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

如果您有任何反馈或问题,请与我们联系!