PrimeNG下拉列表 - 嵌套的ng-template

时间:2018-05-06 15:04:41

标签: angular angular5 primeng ng-template primeng-dropdowns

我找不到如何在角度5.2中使用嵌套的ng-template。

我的应用中有一个使用PrimeNG下拉列表的组件:

@Component({
  selector: 'app-dropdown',
  template: `
    <p-dropdown [options]="options" [(ngModel)]="selected">
         <ng-template let-item pTemplate="selectedItem">
            <span>{{item.label | translate}}</span>
         </ng-template>
         <ng-template let-item pTemplate="item">
            <span>{{item.label | translate}}</span>
         </ng-template>
    </p-dropdown>
  `
})

我需要将它包装在另一个组件中。像这样:

@Component({
      selector: 'app-dropdown-wrapper',
      template: `
        <label>my label</label>
        <app-dropdown [options]='options' [selectedItem]='selectedItem'></app-dropdown>
      `
    })

问题是我不知道在使用包装器组件时如何传递'selectedItem'模板:

 @Component({
     selector: 'app-main',
     template: `
        <app-dropdown-wrapper [options]='options'>
           <ng-template let-item pTemplate="selectedItem">
               <span>{{item.label | translate}}</span>
           </ng-template>
        </app-dropdown-wrapper>
          `
     })

1 个答案:

答案 0 :(得分:1)

我也为同样的问题而苦苦挣扎,直到我终于找到了解决之道。

解决方案是将模板引用作为@ContentChild传递给包装器组件,然后将引用输出到自动完成模板中的容器。

这里是一个例子:

在包装器组件( my-wrapper.component.ts )上声明@ContentChild

/**
 * Pass a template for the autocomplete in this component
 * 
 * @usage
 * Can be passed inside the body of this component as:
 *  <app-my-wrapper ...>
 *      <ng-template ... #item let-obj>...</ng-template>
 *  </app-my-wrapper>
 */
@ContentChild('item') item: TemplateRef<ElementRef>;

请注意,item(在调用@ContentChild('item')时就是您要传递的TemplateRef的名称。因此,在外面,它必须是#item ...或您喜欢的任何名称,只需确保您使用的名称匹配即可。

我面临的下一个挑战是弄清楚如何将上下文从自动完成的包装模板传递到出口中的内部模板。因此,在下面的示例中,我在名为outerContext的外部模板上使用模板变量,该变量要通过*ngTemplateOutlet的上下文传递给内部模板。

诀窍是将上下文作为$implicit传递,该上下文将自动设置为在外部模板上声明的任何变量,在此示例中为obj

还请注意,只有在ng-template未定义(这意味着将模板引用传递到我的包装程序)时,我才打算使用item

因此组件的模板 my-wrapper.component.html 应该如下所示:

<p-autoComplete ...>
    <ng-template let-outerContext *ngIf="item" pTemplate="item">
        <ng-container
            *ngTemplateOutlet="item; context: {$implicit: outerContext}">
        </ng-container>
    </ng-template>
</p-autoComplete>

就是这样!现在您可以像这样使用它:

<app-my-wrapper ... >
    <ng-template #item let-obj>
        <span>{{obj.label | translate}}</span>
        (<em>{{obj.name}}</em>)
    </ng-template>
</app-my-wrapper>