如何包装 Angular 组件并将 ng-template 从外部组件传递到内部组件
How to wrap an Angular Component and pass ng-template from outer to inner component
我正在使用 Angular 5 并尝试将 ng-select 包装在自定义组件中。
我的理由是将它封装起来,以便在需要时可以轻松更换。
如果有更好的方法,请告诉我。
我创建了一个自定义组件,我有各种@Inputs(),它们又被传递给内部 ng-select。这一切都很好。
我的问题是如何正确地将 ng-select custom templates 传递给包装好的 ng-select?
这是我目前所拥有的示例,为了简单起见,我省略了一些输入。
这就是我如何调用传入自定义模板的包装器:
<app-wrapper-select
[items]="cars"
[(selected)]="selectedCars">
<ng-template #labelTemplate ng-label-tmp let-item="item">
<span class="ng-value-label">LABEL {{item.metadata.name}}</span>
<span class="ng-value-icon right" aria-hidden="true">×</span>
</ng-template>
<ng-template #optionTemplate ng-option-tmp let-item="item">
<span class="ng-value-label">OPTION {{item.metadata.name}}</span>
<span class="ng-value-icon right" aria-hidden="true">×</span>
</ng-template>
</app-wrapper-select>
在包装器组件中,我声明模板如下:
@ContentChild('labelTemplate', { read: TemplateRef }) labelTemplate: TemplateRef<any>;
@ContentChild('optionTemplate', { read: TemplateRef }) optionTemplate: TemplateRef<any>;
这是包装组件 html:
<ng-select
[items]="items"
[(ngModel)]="selected">
<ng-template ng-label-tmp let-item="item">
<ng-container *ngTemplateOutlet="labelTemplate; context:{item: item}"></ng-container>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<ng-container *ngTemplateOutlet="optionTemplate; context:{item: item}"></ng-container>
</ng-template>
</ng-select>
上面确实渲染了模板,但标签和选项的所有样式都丢失了,只是在白色背景上显示为文本。
我一定是遗漏了什么,我怎样才能让样式正确呈现?
另一个问题是 ng-select 在每个标签上都有一个关闭按钮,用于将其从 selected 项目和关联的 clear() 方法中删除 - 但是当我在我的模板中使用它时在 ng-select 之外无法识别,例如
<ng-template #labelTemplate ng-label-tmp let-item="item" let-clear="clear">
<span class="ng-value-label">LABEL {{item.metadata.name}}</span>
<span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
</ng-template>
如何在 ng-select 之外的 ng-template 中使用 clear(),有什么方法可以获取对它的引用并调用它吗?
谢谢。
好吧,我已经开始使用这里的解决方案,以防有人像我一样感到困惑。在 IntelliJ 中,当模板输入变量是函数时,它无法识别它们并表示它们不可调用。它确实编译得很好。这也发生在 ngBootstrap 模态以及关闭和关闭方法中。这是我使用的 ng-template,现在可以使用了
<app-wrapper-select
[items]="cars"
[(selected)]="selectedCars">
<ng-template #labelTemplate ng-label-tmp let-item="item" let-clear="clear">
<span class="ng-value-label">{{item.metadata.name}}</span>
<span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
</ng-template>
<ng-template #optionTemplate ng-option-tmp let-item="item">
<span class="ng-value-label">{{item.metadata.name}}</span>
</ng-template>
</app-wrapper-select>
<ng-select
[items]="items"
[(ngModel)]="selected">
<ng-template ng-label-tmp let-item="item" let-clear="clear">
<ng-container *ngTemplateOutlet="labelTemplate; context:{item: item, clear: clear}"></ng-container>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<ng-container *ngTemplateOutlet="optionTemplate; context:{item: item}"></ng-container>
</ng-template>
</ng-select>
我正在使用 Angular 5 并尝试将 ng-select 包装在自定义组件中。 我的理由是将它封装起来,以便在需要时可以轻松更换。 如果有更好的方法,请告诉我。
我创建了一个自定义组件,我有各种@Inputs(),它们又被传递给内部 ng-select。这一切都很好。
我的问题是如何正确地将 ng-select custom templates 传递给包装好的 ng-select?
这是我目前所拥有的示例,为了简单起见,我省略了一些输入。
这就是我如何调用传入自定义模板的包装器:
<app-wrapper-select
[items]="cars"
[(selected)]="selectedCars">
<ng-template #labelTemplate ng-label-tmp let-item="item">
<span class="ng-value-label">LABEL {{item.metadata.name}}</span>
<span class="ng-value-icon right" aria-hidden="true">×</span>
</ng-template>
<ng-template #optionTemplate ng-option-tmp let-item="item">
<span class="ng-value-label">OPTION {{item.metadata.name}}</span>
<span class="ng-value-icon right" aria-hidden="true">×</span>
</ng-template>
</app-wrapper-select>
在包装器组件中,我声明模板如下:
@ContentChild('labelTemplate', { read: TemplateRef }) labelTemplate: TemplateRef<any>;
@ContentChild('optionTemplate', { read: TemplateRef }) optionTemplate: TemplateRef<any>;
这是包装组件 html:
<ng-select
[items]="items"
[(ngModel)]="selected">
<ng-template ng-label-tmp let-item="item">
<ng-container *ngTemplateOutlet="labelTemplate; context:{item: item}"></ng-container>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<ng-container *ngTemplateOutlet="optionTemplate; context:{item: item}"></ng-container>
</ng-template>
</ng-select>
上面确实渲染了模板,但标签和选项的所有样式都丢失了,只是在白色背景上显示为文本。
我一定是遗漏了什么,我怎样才能让样式正确呈现?
另一个问题是 ng-select 在每个标签上都有一个关闭按钮,用于将其从 selected 项目和关联的 clear() 方法中删除 - 但是当我在我的模板中使用它时在 ng-select 之外无法识别,例如
<ng-template #labelTemplate ng-label-tmp let-item="item" let-clear="clear">
<span class="ng-value-label">LABEL {{item.metadata.name}}</span>
<span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
</ng-template>
如何在 ng-select 之外的 ng-template 中使用 clear(),有什么方法可以获取对它的引用并调用它吗?
谢谢。
好吧,我已经开始使用这里的解决方案,以防有人像我一样感到困惑。在 IntelliJ 中,当模板输入变量是函数时,它无法识别它们并表示它们不可调用。它确实编译得很好。这也发生在 ngBootstrap 模态以及关闭和关闭方法中。这是我使用的 ng-template,现在可以使用了
<app-wrapper-select
[items]="cars"
[(selected)]="selectedCars">
<ng-template #labelTemplate ng-label-tmp let-item="item" let-clear="clear">
<span class="ng-value-label">{{item.metadata.name}}</span>
<span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
</ng-template>
<ng-template #optionTemplate ng-option-tmp let-item="item">
<span class="ng-value-label">{{item.metadata.name}}</span>
</ng-template>
</app-wrapper-select>
<ng-select
[items]="items"
[(ngModel)]="selected">
<ng-template ng-label-tmp let-item="item" let-clear="clear">
<ng-container *ngTemplateOutlet="labelTemplate; context:{item: item, clear: clear}"></ng-container>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<ng-container *ngTemplateOutlet="optionTemplate; context:{item: item}"></ng-container>
</ng-template>
</ng-select>