1

我找不到如何在 Angular 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>
          `
     })
4

1 回答 1

1

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

解决方案是将模板引用作为 a 传递@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's 上下文传递给内部模板。

诀窍是传递上下文,$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>
于 2018-10-25T17:05:32.443 回答