mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(list): selection list always firing change event for selectAll and deselectAll (#11029)
This commit is contained in:
committed by
Joey Perrott
parent
385f96dc65
commit
54c0b001d3
@@ -751,6 +751,30 @@ describe('MatSelectionList with forms', () => {
|
||||
expect(fixture.componentInstance.selectedOptions).toEqual(['opt1']);
|
||||
}));
|
||||
|
||||
it('should not dispatch the model change event if nothing changed using selectAll', () => {
|
||||
expect(fixture.componentInstance.modelChangeSpy).not.toHaveBeenCalled();
|
||||
|
||||
selectionListDebug.componentInstance.selectAll();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.modelChangeSpy).toHaveBeenCalledTimes(1);
|
||||
|
||||
selectionListDebug.componentInstance.selectAll();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.modelChangeSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should not dispatch the model change event if nothing changed using selectAll', () => {
|
||||
expect(fixture.componentInstance.modelChangeSpy).not.toHaveBeenCalled();
|
||||
|
||||
selectionListDebug.componentInstance.deselectAll();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(fixture.componentInstance.modelChangeSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('and formControl', () => {
|
||||
@@ -968,13 +992,14 @@ class SelectionListWithTabindexBinding {
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<mat-selection-list [(ngModel)]="selectedOptions">
|
||||
<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-selection-list>`
|
||||
})
|
||||
class SelectionListWithModel {
|
||||
modelChangeSpy = jasmine.createSpy('model change spy');
|
||||
selectedOptions: string[] = [];
|
||||
renderLastOption = true;
|
||||
}
|
||||
|
||||
@@ -221,10 +221,10 @@ export class MatListOption extends _MatListOptionMixinBase
|
||||
return this._element.nativeElement;
|
||||
}
|
||||
|
||||
/** Sets the selected state of the option. */
|
||||
_setSelected(selected: boolean) {
|
||||
/** Sets the selected state of the option. Returns whether the value has changed. */
|
||||
_setSelected(selected: boolean): boolean {
|
||||
if (selected === this._selected) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
this._selected = selected;
|
||||
@@ -236,6 +236,7 @@ export class MatListOption extends _MatListOptionMixinBase
|
||||
}
|
||||
|
||||
this._changeDetector.markForCheck();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +303,6 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
|
||||
|
||||
constructor(private _element: ElementRef, @Attribute('tabindex') tabIndex: string) {
|
||||
super();
|
||||
|
||||
this.tabIndex = parseInt(tabIndex) || 0;
|
||||
}
|
||||
|
||||
@@ -346,14 +346,12 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
|
||||
|
||||
/** Selects all of the options. */
|
||||
selectAll() {
|
||||
this.options.forEach(option => option._setSelected(true));
|
||||
this._reportValueChange();
|
||||
this._setAllOptionsSelected(true);
|
||||
}
|
||||
|
||||
/** Deselects all of the options. */
|
||||
deselectAll() {
|
||||
this.options.forEach(option => option._setSelected(false));
|
||||
this._reportValueChange();
|
||||
this._setAllOptionsSelected(false);
|
||||
}
|
||||
|
||||
/** Sets the focused option of the selection-list. */
|
||||
@@ -479,6 +477,26 @@ export class MatSelectionList extends _MatSelectionListMixinBase implements Focu
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the selected state on all of the options
|
||||
* and emits an event if anything changed.
|
||||
*/
|
||||
private _setAllOptionsSelected(isSelected: boolean) {
|
||||
// Keep track of whether anything changed, because we only want to
|
||||
// emit the changed event when something actually changed.
|
||||
let hasChanged = false;
|
||||
|
||||
this.options.forEach(option => {
|
||||
if (option._setSelected(isSelected)) {
|
||||
hasChanged = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasChanged) {
|
||||
this._reportValueChange();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility to ensure all indexes are valid.
|
||||
* @param index The index to be checked.
|
||||
|
||||
Reference in New Issue
Block a user