【发布时间】:2020-06-30 16:17:17
【问题描述】:
我想创建一个包含ng-select 组件的组件,我将向该组件传递复杂对象的数组以及要在下拉列表中显示的字段以及所选值的定义。使用ng-select,您可以指定要显示的字段 (bindLabel) 并定义一个模板来显示所选值(您可以显示来自对象或其他 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}} 插值到适当的值?当我只使用 {{template}} 而不是带有 innerHTML 的标签时,也会发生同样的情况。如何防止它被呈现为字符串?
我同样有一个标准的
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>
【问题讨论】:
-
你试过
[bindLabel]="displayField"而不是bindLabel="{{displayField}}"吗? -
@noamyg 是的,但结果是一样的——没有插值。
-
有动态模板选项取决于具体的用例,这可能与您的简化代码不同。请记住,AOT 在编译时而不是运行时将模板转换为 JS。
ngTemplateOutletw/ngTemplateOutletContext允许从父级传递预定义的 TemplateRefs。要从带有占位符的字符串中设置innerHTML,最简单的方法是将item传递到使用JS 模板文字的fn 中。解析来自用户的任意 HTML(非常危险!)存在许多非 NG 库。 NG 的DomSanitizer和类似的清理方法试图提供一些针对 XSS 和其他攻击的保护。
标签: angular angular2-template string-interpolation