Angular 2 Select Component 设置初始选择

Posted

技术标签:

【中文标题】Angular 2 Select Component 设置初始选择【英文标题】:Angular 2 Select Component set initial selection 【发布时间】:2016-06-06 11:16:56 【问题描述】:

我正在尝试使用 ngModel 在 Angular 2 中创建一个选择组件包装器。更改选择后,所有事件都会正确触发,但在呈现时我无法设置初始选择。

这是我的组件:

@Component(
selector: 'my-dropdown',
inputs: ['selectedItem', 'items', 'label'],
outputs: ['selectedItemChange'],
template: `
<div class="field">
  <label>label</label>
    <select class="ui search selection dropdown" [ngModel]="selectedItem" (change)="onChange($event.target.value)">
      <option value="" selected>Please Select</option>
      <option *ngFor="#item of items" [value]="item.value">item.label</option>
    </select>
</div>`
)

export class MyDropdownComponent 

items: DropdownValue[];
selectedItem: DropdownValue;
selectedItemChange: EventEmitter<any> = new EventEmitter();

private onChange(newValue) 

    console.log(newValue);
    this.selectedItem = this.items.find(item => item.value == newValue);
    console.log(this.selectedItem);
    this.selectedItemChange.emit(newValue);


我在这样的视图中使用它:

<my-dropdown [items]="selectItems" [(selectedItem)]="itemToSelect" [label]="'Please Select'"></my-dropdown>

当我在初始化时在父组件中设置itemToSelect 值时,它不会在 UI 中设置选定的选项值。

我也尝试使用ngModelChange 事件,但它不会触发更改事件。

【问题讨论】:

【参考方案1】:

itemToSelect 初始设置为对象,因此 MyDropdownComponent 的输入属性初始设置为对象。但是在onChange() 中,字符串值是emit()ted,这会导致itemToSelect 被设置为字符串,因此输入属性变为字符串。不好。

只要始终如一地使用一个对象,它就会起作用。此外,无需在onChange() 中分配this.selectedItem,因为选定的值将从父级向下传播(通常,您永远不应该在组件中设置输入属性——它看起来也很奇怪)。您现在也可以使用ngModelChange

<select class="ui search selection dropdown" [ngModel]="selectedItem.value"
 (ngModelChange)="onChange($event)">

private onChange(newValue) 
    console.log('nv',newValue);
    selectedItem = this.items.find(item => item.value == newValue);
    console.log('si',selectedItem);
    this.selectedItemChange.emit(selectedItem);
  

Plunker

请注意,我没有解决用户选择“请选择”的问题。您需要向onChange() 添加一些逻辑来处理这种情况。

【讨论】:

我正在研究你的 plunker 示例,我的问题是谁或什么定义了“DropdownValue”类型。当我将此代码移出 plunke 环境时,它没有定义。谢谢.... @IrvLennert,这是我的复制粘贴错误(来自 OP 的代码)。不需要它们(我删除了它们)。我使用自己的对象数组,分配给selectItems,因为 OP 没有向我们显示 DropdownValue 类型的定义。 @MarkRajcok 这可行,但是在未设置初始选择时,在实际选定的项目值[ngModel]="selectedItem.value" 上定义 ngModel 会导致错误,您将如何防止这种情况发生? @EnlitenedZA,最初将选定项设置为空值/对象:itemToSelect = value: null; 注意你发送了一个异步事件。首先会触发onchange,比绑定,比自定义Event。您可以通过使用 new EventEmitter(false); 来创建同步事件;【参考方案2】:

当我在初始化时在父组件中设置 itemToSelect 值时,它不会在 UI 中设置选定的选项值。

假设您在父级中使用ngOnInit(),则应在稍后调用的lifecycle hooks 之一中设置值(因为ngOnInit() 中尚不存在子级),请尝试ngAfterViewInit()...

【讨论】:

我用ngOnInit设置选中项,改成ngAfterViewInit,但还是没有在UI中设置初始值。 尝试将ngOnInit也添加到MyDropdownComponent,并从那里调用onChange 收到以下错误:Expression 'itemToSelect' has changed after it was checked. Previous value: 'undefined'. Current value: '[object Object]' 这是一个更改检测问题,请尝试更改该组件的ChangeDetectionStrategy,以确认它是否正常工作。您真的应该尝试清理/改进您的逻辑,因为这就是导致问题的原因。父级正在设置一个值,该值触发一个正在设置一个值的事件并发出另一个正在设置第一个值的事件......有点难以理解(; 例如,您可以将[(selectedItem)]="itemToSelect" 扩展为一个事件和一个属性绑定。 [selectedItem]="itemToSelect" (selectionChanged)="parentNotifiedAboutChange()"

以上是关于Angular 2 Select Component 设置初始选择的主要内容,如果未能解决你的问题,请参考以下文章

Angular之父子路由

Angular2 切换/打开 ng2-select 下拉菜单

如何在 Angular 2 项目中使用 types/select2?

Angular 2 Select - 从 Web 服务问题中加载数据

Angular ui-select2 - 隐藏组件的初始绘图/渲染

Jest 单元测试中的 Angular 循环依赖问题