Skip to content

Commit bd0b011

Browse files
committed
chore(selection): switch option and pseudo checkbox to OnPush change detection
* 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 eedf36c commit bd0b011

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

src/lib/core/option/optgroup.ts

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

9-
import {Component, ViewEncapsulation, ContentChildren, QueryList, Input} from '@angular/core';
9+
import {
10+
Component,
11+
ViewEncapsulation,
12+
ContentChildren,
13+
QueryList,
14+
Input,
15+
ChangeDetectionStrategy,
16+
} from '@angular/core';
1017
import {mixinDisabled, CanDisable} from '../common-behaviors/disabled';
1118

1219
// Boilerplate for applying mixins to MdOptgroup.
@@ -25,6 +32,7 @@ let _uniqueOptgroupIdCounter = 0;
2532
selector: 'md-optgroup, mat-optgroup',
2633
templateUrl: 'optgroup.html',
2734
encapsulation: ViewEncapsulation.None,
35+
changeDetection: ChangeDetectionStrategy.OnPush,
2836
inputs: ['disabled'],
2937
host: {
3038
'class': 'mat-optgroup',

src/lib/core/option/option.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616
ViewEncapsulation,
1717
Inject,
1818
Optional,
19+
ChangeDetectionStrategy,
20+
ChangeDetectorRef,
1921
} from '@angular/core';
2022
import {ENTER, SPACE} from '../keyboard/keycodes';
2123
import {coerceBooleanProperty} from '@angular/cdk';
@@ -55,19 +57,27 @@ export class MdOptionSelectionChange {
5557
'class': 'mat-option',
5658
},
5759
templateUrl: 'option.html',
58-
encapsulation: ViewEncapsulation.None
60+
encapsulation: ViewEncapsulation.None,
61+
changeDetection: ChangeDetectionStrategy.OnPush,
5962
})
6063
export class MdOption {
6164
private _selected: boolean = false;
6265
private _active: boolean = false;
66+
private _multiple: boolean = false;
6367

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

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

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

7282
/** The unique ID of the option. */
7383
get id() { return this._id; }
@@ -88,6 +98,7 @@ export class MdOption {
8898

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

@@ -113,12 +124,14 @@ export class MdOption {
113124
/** Selects the option. */
114125
select(): void {
115126
this._selected = true;
127+
this._changeDetectorRef.markForCheck();
116128
this._emitSelectionChangeEvent();
117129
}
118130

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

@@ -133,7 +146,10 @@ export class MdOption {
133146
* events will display the proper options as active on arrow key events.
134147
*/
135148
setActiveStyles(): void {
136-
this._active = true;
149+
if (!this._active) {
150+
this._active = true;
151+
this._changeDetectorRef.markForCheck();
152+
}
137153
}
138154

139155
/**
@@ -142,7 +158,10 @@ export class MdOption {
142158
* events will display the proper options as active on arrow key events.
143159
*/
144160
setInactiveStyles(): void {
145-
this._active = false;
161+
if (this._active) {
162+
this._active = false;
163+
this._changeDetectorRef.markForCheck();
164+
}
146165
}
147166

148167
/** Ensures the option is selected when activated from the keyboard. */
@@ -162,6 +181,7 @@ export class MdOption {
162181
_selectViaInteraction(): void {
163182
if (!this.disabled) {
164183
this._selected = this.multiple ? !this._selected : true;
184+
this._changeDetectorRef.markForCheck();
165185
this._emitSelectionChangeEvent(true);
166186
}
167187
}

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)