Angular 2 Select Component set initial selection

2019-05-07 04:48发布

I am trying to create a select component wrapper in Angular 2 using ngModel. The events all fire off correctly once the selection is changed but I cannot set the initial selection when it's rendered.

This is my component:

@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);
}
}

And I'm using it in the view like this:

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

When I set the itemToSelect value in the parent component on init, it does not set the selected option value in the UI.

I have also tried to use the ngModelChange event but it does not fire a change event.

2条回答
forever°为你锁心
2楼-- · 2019-05-07 05:16

When I set the itemToSelect value in the parent component on init, it does not set the selected option value in the UI.

Assuming you are using ngOnInit() in the parent, you should set value in one of the lifecycle hooks that are called later (because child doesn't yet exist in ngOnInit()), try ngAfterViewInit()...

查看更多
叛逆
3楼-- · 2019-05-07 05:32

itemToSelect is initially set to an object, so the input property of MyDropdownComponent is initially set to an object. But then in onChange() a string value is emit()ted, which then causes itemToSelect to be set to a string, and hence the input property becomes a string. Not good.

Just consistently use an object and it will work. Also, there is no need to assign this.selectedItem in onChange(), since the selected value will propagate back down from the parent (in general, you should never set input properties in the component – it also looks weird). You can also use ngModelChange now too:

<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

Note that I did not solve the issue of the user selecting "Please select". You'll need to add some logic to onChange() to handle that case.

查看更多
登录 后发表回答