在子组件中将ng-content传递给ng-template元素不会绑定到属性

时间:2018-06-21 14:08:17

标签: angular angular-ngselect

我有一个名为 select.component 的组件(选择器:“ app-select”),该组件使用typeahead搜索用户(为简单起见,我将其省略了)。然后,我想通过绑定到ng-template中的项目来显示姓名和employeeId。

    <ng-select>
       <ng-template ng-option-tmp let-item="item">
          {{item.name}}</br>
          {{item.employeeId}}
       </ng-template
    </ng-select>

由于我们在应用程序中使用了许多此类ng-select元素,因此我将select.component设置为其他父组件使用的可重用组件。因此,我想使ng-template部分成为动态的,并使其从父组件中传入。我将select.component更改为如下所示:

        <ng-select>
           <ng-template ng-option-tmp let-item="item">
              <ng-content></ng-content>
           </ng-template
        </ng-select>

然后我有了 user.component ,它使用内容投影在select.component中填充ng模板,如下所示:

<app-select>
   {{item.name}}</br>
   {{item.employeeId}}
</app-select>

这里的问题是,当内容投影将app-select的内部html传递给ng-template时,{{item.name}}和{{item.employeeId}}尚未在ng-template中进行评估。在项目下拉列表中,我看到的是{{item.name}},而不是实际的名称值。

我怎样才能最好地做到这一点?我确实需要父组件能够指定下拉项目应如何使select.component完全可重用。

看到我的stackblitz

3 个答案:

答案 0 :(得分:1)

您需要在组件中传递代码并捕获选择的组件

<app-select>
  <ng-select [items]="items" bindLabel="name" placeholder="Works">
    <ng-template ng-option-tmp let-item="item">
        {{item.name}}<br/>
        {{item.employeeId}}
  </ng-template>
</ng-select>
</app-select>

然后您需要使用

<ng-content></ng-content>

在您选择的组件中

这样,您将能够实现自己想要的东西。

答案 1 :(得分:0)

如果没有任何结构指令或模板ref变量,

ng-template将永远无法工作。您可以使用ng-container代替ng-template.sorry缺少任何东西,因为我已经从手机中回答了这个问题

答案 2 :(得分:0)

我同意将通用设置封装在组件中,并允许其余的设置由组件的使用者提供。

当父级提供模板时,NgSelect使用@ContentChild()来获取组件标签中提供的模板。我怀疑<ng-content>尚不可用,因为ngAfterContentInit生命周期挂钩在ngAfterViewInit之前被调用。

另一种方法是接受TemplateRef作为<app-select>的输入,并在视图初始化后手动设置NgSelect的optionTemplate

export class SelectComponent implements AfterViewInit {
  @Input() items: any[];
  @Input() optionTemplate: TemplateRef<any>; // The options template to provide to ng-select

  @ViewChild(NgSelectComponent) ngSelect: NgSelectComponent; // A reference to the ng-select component

  // Once @ViewChild is defined after view init
  ngAfterViewInit() {
    if (this.optionTemplate) {
      // Manually assign ng-select's optionTemplate from the input
      this.ngSelect.optionTemplate = this.optionTemplate;
    }
  }
}

然后,您可以传入可通过参考变量进行参考的模板:

<app-select [items]="items" [optionTemplate]="appSelectOption">
</app-select>

<ng-template #appSelectOption let-item="item">
  {{item.name}}<br/>
  {{item.employeeId}}
</ng-template>

这样,您可以将模板出口上下文(let-item="item")保留在使用变量的相同区域。

查看fork of your StackBlitz

相关问题