Skip to content

Commit 70117ff

Browse files
crisbetojelbourn
authored andcommitted
chore(selection): switch option and pseudo checkbox to OnPush change detection (#5585)
* Switches the MdPseudoCheckbox, MdOption and MdOptgroup to OnPush change detection. * Fixes a few cases in MdOption where the UI state wasn't being updated properly. Relates to #5035.
1 parent bcf4826 commit 70117ff

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

src/lib/core/option/optgroup.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {Component, ViewEncapsulation, Input} from '@angular/core';
9+
import {Component, ViewEncapsulation, Input, ChangeDetectionStrategy} from '@angular/core';
1010
import {mixinDisabled, CanDisable} from '../common-behaviors/disabled';
1111

1212
// Boilerplate for applying mixins to MdOptgroup.
@@ -25,6 +25,7 @@ let _uniqueOptgroupIdCounter = 0;
2525
selector: 'md-optgroup, mat-optgroup',
2626
templateUrl: 'optgroup.html',
2727
encapsulation: ViewEncapsulation.None,
28+
changeDetection: ChangeDetectionStrategy.OnPush,
2829
inputs: ['disabled'],
2930
host: {
3031
'class': 'mat-optgroup',

src/lib/core/option/option.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
ViewEncapsulation,
1616
Inject,
1717
Optional,
18+
ChangeDetectionStrategy,
19+
ChangeDetectorRef,
1820
} from '@angular/core';
1921
import {ENTER, SPACE} from '../keyboard/keycodes';
2022
import {coerceBooleanProperty} from '@angular/cdk';
@@ -54,19 +56,27 @@ export class MdOptionSelectionChange {
5456
'class': 'mat-option',
5557
},
5658
templateUrl: 'option.html',
57-
encapsulation: ViewEncapsulation.None
59+
encapsulation: ViewEncapsulation.None,
60+
changeDetection: ChangeDetectionStrategy.OnPush,
5861
})
5962
export class MdOption {
6063
private _selected: boolean = false;
6164
private _active: boolean = false;
65+
private _multiple: boolean = false;
6266

6367
/** Whether the option is disabled. */
6468
private _disabled: boolean = false;
6569

6670
private _id: string = `md-option-${_uniqueIdCounter++}`;
6771

6872
/** Whether the wrapping component is in multiple selection mode. */
69-
multiple: boolean = false;
73+
get multiple() { return this._multiple; }
74+
set multiple(value: boolean) {
75+
if (value !== this._multiple) {
76+
this._multiple = value;
77+
this._changeDetectorRef.markForCheck();
78+
}
79+
}
7080

7181
/** The unique ID of the option. */
7282
get id() { return this._id; }
@@ -87,6 +97,7 @@ export class MdOption {
8797

8898
constructor(
8999
private _element: ElementRef,
100+
private _changeDetectorRef: ChangeDetectorRef,
90101
@Optional() public readonly group: MdOptgroup,
91102
@Optional() @Inject(MATERIAL_COMPATIBILITY_MODE) public _isCompatibilityMode: boolean) {}
92103

@@ -112,12 +123,14 @@ export class MdOption {
112123
/** Selects the option. */
113124
select(): void {
114125
this._selected = true;
126+
this._changeDetectorRef.markForCheck();
115127
this._emitSelectionChangeEvent();
116128
}
117129

118130
/** Deselects the option. */
119131
deselect(): void {
120132
this._selected = false;
133+
this._changeDetectorRef.markForCheck();
121134
this._emitSelectionChangeEvent();
122135
}
123136

@@ -132,7 +145,10 @@ export class MdOption {
132145
* events will display the proper options as active on arrow key events.
133146
*/
134147
setActiveStyles(): void {
135-
this._active = true;
148+
if (!this._active) {
149+
this._active = true;
150+
this._changeDetectorRef.markForCheck();
151+
}
136152
}
137153

138154
/**
@@ -141,7 +157,10 @@ export class MdOption {
141157
* events will display the proper options as active on arrow key events.
142158
*/
143159
setInactiveStyles(): void {
144-
this._active = false;
160+
if (this._active) {
161+
this._active = false;
162+
this._changeDetectorRef.markForCheck();
163+
}
145164
}
146165

147166
/** Ensures the option is selected when activated from the keyboard. */
@@ -161,6 +180,7 @@ export class MdOption {
161180
_selectViaInteraction(): void {
162181
if (!this.disabled) {
163182
this._selected = this.multiple ? !this._selected : true;
183+
this._changeDetectorRef.markForCheck();
164184
this._emitSelectionChangeEvent(true);
165185
}
166186
}

src/lib/core/selection/pseudo-checkbox/pseudo-checkbox.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Input,
1313
ElementRef,
1414
Renderer2,
15+
ChangeDetectionStrategy,
1516
} from '@angular/core';
1617
import {CanColor, mixinColor} from '../../common-behaviors/color';
1718

@@ -40,6 +41,7 @@ export const _MdPseudoCheckboxBase = mixinColor(MdPseudoCheckboxBase, 'accent');
4041
@Component({
4142
moduleId: module.id,
4243
encapsulation: ViewEncapsulation.None,
44+
changeDetection: ChangeDetectionStrategy.OnPush,
4345
selector: 'md-pseudo-checkbox, mat-pseudo-checkbox',
4446
styleUrls: ['pseudo-checkbox.css'],
4547
inputs: ['color'],

0 commit comments

Comments
 (0)