使用 ng-select 插入动态模板
Interpolate a dynamic template with ng-select
我想创建一个组件,其中包含一个 ng-select
组件,我将向其传递一组复杂对象和要在下拉列表中显示哪些字段的定义以及 selected 值.使用 ng-select
您可以指定要显示的字段 (bindLabel
) 并定义一个模板来显示 selected 值(您可以显示对象中的一个或多个字段,或其他 HTML 标记)。我可以传递 bindLabel
的值,但不知道如何插入模板。
例如,这就是我通常使用 ng-select
的方式。在这种情况下,我显示了对象的两个字段和一些 HTML(加粗缩写字段),并在下拉列表中列出缩写字段:
子组件
items = [
{ name: 'United States', abbreviation: 'US' },
{ name: 'United Kingdom', abbreviation: 'UK' },
{ name: 'Canada', abbreviation: 'CA' }
];
displayField = 'abbreviation';
子模板
<ng-select [items]="items"
bindLabel="displayField"
[(ngModel)]="model"
name="ngselect"
(change)=emitModelChanged()>
<ng-template ng-label-tmp let-item="item">
<b>{{item.abbreviation}}</b> - {{item.name}}
</ng-template>
</ng-select>
为了从父组件动态配置它,我将 items
、displayField
和 template
作为输入传递:
父组件
selectedTemplate = '<b>{{item.name}}</b> - {{item.abbreviation}}';
父模板
<child-component [model]=model
[items]=items
[displayField]="'abbreviation'"
[template]=selectedTemplate
(update)=updateModel($event)></child-component>
子组件
@Input() items;
@Input() displayField; //what field shows in dropdown options
@Input() template; // what shows for selected value in combobox
@Input() model;
@Output() update: EventEmitter<any> = new EventEmitter(); //emit back to parent
子组件模板
<ng-select [items]="items"
bindLabel="{{displayField}}"
[(ngModel)]="model"
name="ngselect"
(change)=modelChanged()>
<ng-template let-item="item">
<label [innerHTML]="template"></label>
</ng-template>
</ng-select>
虽然解释了“模板”的粗体标记,但未插入数据字段,值按字面显示为
{{item.name}} - {{item.abbreviation}}
它是否失去了范围,因此没有将 {{item.name}} 插入到适当的值?当我不使用带有 innerHTML 的标签而只使用 {{template}} 时,也会发生同样的情况。如何防止将其呈现为字符串?
我同样在标准
selectField = 'item.'+this.displayField; // (equivalent to item.abbreviation)
<select #standardSelect [(ngModel)]="model" (change)=modelChanged() >
<!-- Also getting interpolating error here. Below renders as a string "item.abbreviation" -->
<option *ngFor="let item of items" [ngValue]="item">{{selectField}}</option>
<!-- This also renders as a string -->
<!-- <option *ngFor="let item of items" [ngValue]="item" [innerHTML]="selectField"></option> -->
<!-- Hardcoded value below works -->
<!-- <option *ngFor="let item of items" [ngValue]="item">{{item.abbreviation}}</option> -->
</select>
您可以将模板路径放入您的组件并使用 ng-container
呈现它,但您需要使用 ContentChild
来处理模板引用。对于多个模板,使用 #
命名以将它们与 ContentChild
引用相匹配。你可以试试example
使用 TemplateRef 引用外部模板
import { TemplateRef } from '@angular/core';
@Component({
selector: 'ng-select-accessible[displayField]',
templateUrl: './ng-select-accessible.component.html',
styleUrls: [ './ng-select-accessible.component.scss' ]
})
export class NgSelectAccessibleComponent {
@ContentChild('labelTemplate') labelTemplate: TemplateRef<any>;;
@ContentChild('optionTemplate') optionTemplate: TemplateRef<any>;;
}
使用 ng-container 将外部模板放置在项目模板中
<div class='styled-select' aria-hidden=true>
<ng-select [items]="items"
[placeholder]=placeholder
[(ngModel)]="model"
name="ngselect"
(change)=modelChanged()
attr.aria-label={{ariaLabel}}>
<ng-template ng-label-tmp let-item="item">
<ng-container
*ngTemplateOutlet="labelTemplate; context: { $implicit: item }">
</ng-container>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<ng-container
*ngTemplateOutlet="optionTemplate; context: { $implicit: item }">
</ng-container>
</ng-template>
</ng-select>
</div>
在 ng-template 中定义项目视图如下
<ng-select-accessible
[model]=model
[items]=items
[displayField]="'abbreviation'"
[placeholder]="'custom placeholder'"
(update)=updateModel($event)
[ariaLabel]="'Select a number'">
<ng-template #labelTemplate let-item>
<label>
<b>{{item.name}}</b> - {{item.abbreviation}}
</label>
</ng-template>
<ng-template #optionTemplate let-item>
<label>
<b>{{item.name}}</b>
</label>
</ng-template>
</ng-select-accessible>
我觉得这篇文章不错about ng-template
我想创建一个组件,其中包含一个 ng-select
组件,我将向其传递一组复杂对象和要在下拉列表中显示哪些字段的定义以及 selected 值.使用 ng-select
您可以指定要显示的字段 (bindLabel
) 并定义一个模板来显示 selected 值(您可以显示对象中的一个或多个字段,或其他 HTML 标记)。我可以传递 bindLabel
的值,但不知道如何插入模板。
例如,这就是我通常使用 ng-select
的方式。在这种情况下,我显示了对象的两个字段和一些 HTML(加粗缩写字段),并在下拉列表中列出缩写字段:
子组件
items = [
{ name: 'United States', abbreviation: 'US' },
{ name: 'United Kingdom', abbreviation: 'UK' },
{ name: 'Canada', abbreviation: 'CA' }
];
displayField = 'abbreviation';
子模板
<ng-select [items]="items"
bindLabel="displayField"
[(ngModel)]="model"
name="ngselect"
(change)=emitModelChanged()>
<ng-template ng-label-tmp let-item="item">
<b>{{item.abbreviation}}</b> - {{item.name}}
</ng-template>
</ng-select>
为了从父组件动态配置它,我将 items
、displayField
和 template
作为输入传递:
父组件
selectedTemplate = '<b>{{item.name}}</b> - {{item.abbreviation}}';
父模板
<child-component [model]=model
[items]=items
[displayField]="'abbreviation'"
[template]=selectedTemplate
(update)=updateModel($event)></child-component>
子组件
@Input() items;
@Input() displayField; //what field shows in dropdown options
@Input() template; // what shows for selected value in combobox
@Input() model;
@Output() update: EventEmitter<any> = new EventEmitter(); //emit back to parent
子组件模板
<ng-select [items]="items"
bindLabel="{{displayField}}"
[(ngModel)]="model"
name="ngselect"
(change)=modelChanged()>
<ng-template let-item="item">
<label [innerHTML]="template"></label>
</ng-template>
</ng-select>
虽然解释了“模板”的粗体标记,但未插入数据字段,值按字面显示为
{{item.name}} - {{item.abbreviation}}
它是否失去了范围,因此没有将 {{item.name}} 插入到适当的值?当我不使用带有 innerHTML 的标签而只使用 {{template}} 时,也会发生同样的情况。如何防止将其呈现为字符串?
我同样在标准
selectField = 'item.'+this.displayField; // (equivalent to item.abbreviation)
<select #standardSelect [(ngModel)]="model" (change)=modelChanged() >
<!-- Also getting interpolating error here. Below renders as a string "item.abbreviation" -->
<option *ngFor="let item of items" [ngValue]="item">{{selectField}}</option>
<!-- This also renders as a string -->
<!-- <option *ngFor="let item of items" [ngValue]="item" [innerHTML]="selectField"></option> -->
<!-- Hardcoded value below works -->
<!-- <option *ngFor="let item of items" [ngValue]="item">{{item.abbreviation}}</option> -->
</select>
您可以将模板路径放入您的组件并使用 ng-container
呈现它,但您需要使用 ContentChild
来处理模板引用。对于多个模板,使用 #
命名以将它们与 ContentChild
引用相匹配。你可以试试example
使用 TemplateRef 引用外部模板
import { TemplateRef } from '@angular/core';
@Component({
selector: 'ng-select-accessible[displayField]',
templateUrl: './ng-select-accessible.component.html',
styleUrls: [ './ng-select-accessible.component.scss' ]
})
export class NgSelectAccessibleComponent {
@ContentChild('labelTemplate') labelTemplate: TemplateRef<any>;;
@ContentChild('optionTemplate') optionTemplate: TemplateRef<any>;;
}
使用 ng-container 将外部模板放置在项目模板中
<div class='styled-select' aria-hidden=true>
<ng-select [items]="items"
[placeholder]=placeholder
[(ngModel)]="model"
name="ngselect"
(change)=modelChanged()
attr.aria-label={{ariaLabel}}>
<ng-template ng-label-tmp let-item="item">
<ng-container
*ngTemplateOutlet="labelTemplate; context: { $implicit: item }">
</ng-container>
</ng-template>
<ng-template ng-option-tmp let-item="item">
<ng-container
*ngTemplateOutlet="optionTemplate; context: { $implicit: item }">
</ng-container>
</ng-template>
</ng-select>
</div>
在 ng-template 中定义项目视图如下
<ng-select-accessible
[model]=model
[items]=items
[displayField]="'abbreviation'"
[placeholder]="'custom placeholder'"
(update)=updateModel($event)
[ariaLabel]="'Select a number'">
<ng-template #labelTemplate let-item>
<label>
<b>{{item.name}}</b> - {{item.abbreviation}}
</label>
</ng-template>
<ng-template #optionTemplate let-item>
<label>
<b>{{item.name}}</b>
</label>
</ng-template>
</ng-select-accessible>
我觉得这篇文章不错about ng-template