mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(list): selection list not marking options as selected correctly when setting value with duplicates (#13363)
Along the same lines as #13361. Fixes the selection list not marking all selected options correctly when an array with duplicate values is assigned programmatically.
This commit is contained in:
committed by
vivian-hu
parent
56f2e50273
commit
bef9a17c62
@@ -789,7 +789,7 @@ describe('MatSelectionList with forms', () => {
|
||||
|
||||
expect(fixture.componentInstance.selectedOptions).toEqual(['opt2', 'opt3']);
|
||||
|
||||
fixture.componentInstance.renderLastOption = false;
|
||||
fixture.componentInstance.options.pop();
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
@@ -829,6 +829,20 @@ describe('MatSelectionList with forms', () => {
|
||||
expect(fixture.componentInstance.modelChangeSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should be able to programmatically set an array with duplicate values', fakeAsync(() => {
|
||||
fixture.componentInstance.options = ['one', 'two', 'two', 'two', 'three'];
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
listOptions = fixture.debugElement.queryAll(By.directive(MatListOption))
|
||||
.map(optionDebugEl => optionDebugEl.componentInstance);
|
||||
|
||||
fixture.componentInstance.selectedOptions = ['one', 'two', 'two'];
|
||||
fixture.detectChanges();
|
||||
tick();
|
||||
|
||||
expect(listOptions.map(option => option.selected)).toEqual([true, true, true, false, false]);
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
@@ -1076,15 +1090,13 @@ class SelectionListWithTabindexBinding {
|
||||
@Component({
|
||||
template: `
|
||||
<mat-selection-list [(ngModel)]="selectedOptions" (ngModelChange)="modelChangeSpy()">
|
||||
<mat-list-option value="opt1">Option 1</mat-list-option>
|
||||
<mat-list-option value="opt2">Option 2</mat-list-option>
|
||||
<mat-list-option value="opt3" *ngIf="renderLastOption">Option 3</mat-list-option>
|
||||
<mat-list-option *ngFor="let option of options" [value]="option">{{option}}</mat-list-option>
|
||||
</mat-selection-list>`
|
||||
})
|
||||
class SelectionListWithModel {
|
||||
modelChangeSpy = jasmine.createSpy('model change spy');
|
||||
selectedOptions: string[] = [];
|
||||
renderLastOption = true;
|
||||
options = ['opt1', 'opt2', 'opt3'];
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
||||
@@ -473,13 +473,21 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
|
||||
private _setOptionsFromValues(values: string[]) {
|
||||
this.options.forEach(option => option._setSelected(false));
|
||||
|
||||
values
|
||||
.map(value => {
|
||||
return this.options.find(option =>
|
||||
this.compareWith ? this.compareWith(option.value, value) : option.value === value);
|
||||
})
|
||||
.filter(Boolean)
|
||||
.forEach(option => option!._setSelected(true));
|
||||
values.forEach(value => {
|
||||
const correspondingOption = this.options.find(option => {
|
||||
// Skip options that are already in the model. This allows us to handle cases
|
||||
// where the same primitive value is selected multiple times.
|
||||
if (option.selected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.compareWith ? this.compareWith(option.value, value) : option.value === value;
|
||||
});
|
||||
|
||||
if (correspondingOption) {
|
||||
correspondingOption._setSelected(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Returns the values of the selected options. */
|
||||
|
||||
Reference in New Issue
Block a user