Angular 2选择组件如何设置初始选项

4
我正在尝试使用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事件,但它不会触发更改事件。
2个回答

6

itemToSelect最初被设置为一个对象,因此MyDropdownComponent的输入属性最初也被设置为一个对象。但是在onChange()中,一个字符串值被emit(),这导致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”。当我将此代码移出 Plunker 环境时,它未被定义。谢谢... - Irv Lennert
@IrvLennert,这是我复制粘贴时犯的错误(来自OP的代码)。它们不需要(我已经删除了它们)。由于OP没有向我们展示DropdownValue类型的定义,因此我使用了自己的对象数组分配给selectItems - Mark Rajcok
@MarkRajcok 这个方法是可行的,但是在实际选择项的值上定义ngModel [ngModel] =“selectedItem.value” 会在未设置初始选择时导致错误,你有什么解决办法吗? - EnlitenedZA
1
@EnlitenedZA,将所选项目最初设置为null值/对象:itemToSelect = {value: null}; - Mark Rajcok
请注意,您正在发送一个异步事件。首先触发 onchange,然后是绑定,最后是自定义事件。您可以通过使用 new EventEmitter(false) 创建同步事件。 - Andreas Dyballa

1
当我在父组件中设置itemToSelect值时,它不会在UI中设置所选的选项值。
假设您在父级中使用ngOnInit(),则应在稍后调用的一个lifecycle hooks中设置值(因为在ngOnInit()中子项尚不存在),请尝试ngAfterViewInit()...

我曾使用 ngOnInit 来设置选定的项目,现在改为使用 ngAfterViewInit,但仍无法在 UI 中设置初始值。 - EnlitenedZA
尝试在MyDropdownComponent中添加ngOnInit,并从那里调用onChange - Sasxa
这是一个变更检测问题,请尝试更改该组件的“ChangeDetectionStrategy”,以确认其是否正常工作。您应该真正尝试清理/改进您的逻辑,因为这就是导致问题的原因。父级正在设置一个值,触发了一个事件,该事件又设置了一个值并发出了另一个事件,这有点难以跟踪 (; - Sasxa
例如,您可以将[(selectedItem)]="itemToSelect"扩展为一个事件和一个属性绑定。[selectedItem]="itemToSelect" (selectionChanged)="parentNotifiedAboutChange()" - Sasxa
我不确定哪些逻辑可以改进 - 它是一个选择器的包装器,您传入可选择的项目和所选项目的引用,当设置父项目时,它应该更新UI,在UI选择中更改值时,它应该更改绑定的父模型。有更简单的方法吗? - EnlitenedZA
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接