fix(checkbox, slide-toggle): no margin if content is projected #12973
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Usually if the label of the checkbox or slide-toggle is empty, we remove the margin between label container and thumb/check because otherwise there would be too much spacing. Currently if developers use a component inside of the checkbox or slide-toggle in order to render the label, the margin is accidentally removed and the label looks misplaced.
This is because the
cdkObserveContent
event runs outside of theNgZone
and no change detection round checks the checkbox or slide-toggle.Simple demo
Why
detectChanges
and not ngZone.run()?Creating a new zone fork e.g.
ngZone.run(() => {})
causes theonMicrotaskEmpty
to trigger and dirty check all components which are explicitly "markForChecked or not using
OnPush`.Since
cdkObserveContent
emits an @output() the checkbox will be automatically marked for check, but due to emitting outside ofNgZone
, just no change detection will run becauseonMicrotaskEmpty
doesn't fire after callback.So the best solution for now is:
Use explicitly
detectChanges
because it would then just check the checkbox and it's children. Since we know that only the margin class binding needs to be updated, this is way better than triggering a global dirty-check.If we would use
ngZone.run(() => {}
it would cause Angular to check all components in the application which are marked for check or not usingOnPush
(which is very likely)Fixes #4720