-
Notifications
You must be signed in to change notification settings - Fork 6.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(radio): Make MdRadioButton change detection strategy OnPush #2526
Conversation
src/lib/radio/radio.ts
Outdated
} | ||
set labelPosition(v: 'before' | 'after') { | ||
this._labelPosition = v | ||
if (this._radios) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary; the individual radios have a getter that reads the value from the group if it exists without clobbering its own value.
src/lib/radio/radio.ts
Outdated
} | ||
set ariaLabel(value: string) { | ||
this._ariaLabel = value; | ||
this._change.markForCheck(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't think calling markForCheck
for every property shouldn't be necessary; for anything that is an @Input
Angular will do change detection as needed when the value is changed via a template binding. The only thing I know of that needs to change is that the writeValue
function needs to call markForCheck
, since the template binding is on ngModel
(which isn't an @Input
of the component).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then there's a bug for OnPush since the properties are not updated when their values changed.
The writeValue
function is in MdRadioButtonGroup
which is a directive
and has no changeDetection
strategy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jelbourn your understanding is correct, an @Input()
property updated via a binding would mark the components for change detection. (it would not if it accessed directly, ie myDirective.inputProperty = ...
in some component).
Then there's a bug for OnPush since the properties are not updated when their values changed.
I'm not sure to get what you mean here.
Only components are nodes in the change detection tree. Directives are checked by the CD together with their component and I expect that setting any of their input would have the same effect as setting a component input - I have to double check this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For labelPosition
and disabled
, group buttons' values depend on group's values. When the group's disabled
changed, the button's get disabled
also changed but set disabled
is not called and button's _disabled
is not changed. We need to let buttons markForCheck()
when the group value changed. I added a _groupValueChanged()
function but not sure it's the right way to do.
@vicb Is this the way |
ec34eb8
to
e257577
Compare
e257577
to
1ca794f
Compare
6089d3a
to
7f4c885
Compare
@tinayuangao I'm trying to clean up old PRs; can you rebase this? Revisiting this PR, I think what's missing is, for each |
7178df1
to
0ccedce
Compare
Synced and added some comments |
0ccedce
to
ea16bbc
Compare
src/lib/radio/radio.ts
Outdated
set disabled(value: boolean) { | ||
this._disabled = coerceBooleanProperty(value); | ||
// Update rippleDisabled | ||
this._changeDetector.markForCheck(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you elaborate on what this comment means? I don't see why you would need this in the setter since disabled
is an @Input
src/lib/radio/radio.ts
Outdated
this._labelPosition = (v == 'before') ? 'before' : 'after'; | ||
if (this._radios) { | ||
this._radios.forEach(radio => radio._groupValueChanged()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this part should be broken out into its own function
if (this._radios) {
this._radios.forEach(radio => radio._groupValueChanged());
}
Something like _markRadiosForCheck
src/lib/radio/radio.ts
Outdated
@@ -427,6 +466,12 @@ export class MdRadioButton implements OnInit, AfterViewInit, OnDestroy { | |||
this._focusOriginMonitor.focusVia(this._inputElement.nativeElement, this._renderer, 'keyboard'); | |||
} | |||
|
|||
_groupValueChanged() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just call this function _markForCheck
with a comment like
/**
* Marks the radio button as needing checking for change detection.
* This method is exposed because the parent radio group will directly
* update bound properties of the radio button.
*/
@tinayuangao poke on this one 👈 |
ea16bbc
to
0e4dfdc
Compare
Comments addressed. Please take another look. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a last couple of comments.
Add the "merge_ready" label when it's ready for submit
src/lib/radio/radio.ts
Outdated
this._disabled = value; | ||
if (this._radios) { | ||
// Update radios disabled state | ||
this._radios.forEach((r) => r._markForCheck()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call _markRadiosForCheck()
here?
src/lib/radio/radio.ts
Outdated
} | ||
} | ||
|
||
constructor(private _change: ChangeDetectorRef) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call this _changeDetector
, since _change
could be confused with the change event
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Fixes #2491
R: @jelbourn