-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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(forms): handle standalone <form>
tag in NgControlStatusGroup
directive correctly
#40344
Conversation
…tusGroup` directive The `NgControlStatusGroup` directive is shared between template-driven and reactive form modules. In cases when only reactive forms module is present, the `NgControlStatusGroup` directive is still activated on all `<form>` elements, but if there is no other reactive directive applied (such as `formGroup`), corresponding `ControlContainer` token is missing, thus causing exceptions (since `NgControlStatusGroup` directive relies on it to determine the status). This commit updates the logic to handle the case when no `ControlContainer` is present (effectively making directive logic a noop in this case). Alternative approach (more risky) worth considering in the future is to split the `NgControlStatusGroup` into 2 directives with different set of selectors and include them into template-driven and reactive modules separately. The downside is that these directives might be activated simultaneously on the same element (e.g. `<form>`), effectively doing the work twice. Resolves angular#38391.
<form>
tag correctly in NgControlStatusGroup
directive<form>
tag in NgControlStatusGroup
directive correctly
this._cd = cd; | ||
} | ||
|
||
get ngClassUntouched(): boolean { | ||
return this._cd.control ? this._cd.control.untouched : false; | ||
return this._cd?.control ? this._cd.control.untouched : false; |
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 this be:
return this._cd?.control ? this._cd.control.untouched : false; | |
return this._cd?.control?.untouched ?? false; |
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.
Great idea (I've updated the change), thanks @petebacondarwin! 👍
I was also thinking to refactor that code in the followup PR to get rid of duplicate getters.
Current code:
export const ngControlStatusHost = {
'[class.ng-untouched]': 'ngClassUntouched',
'[class.ng-touched]': 'ngClassTouched',
...
How it may look like:
export const ngControlStatusHost = {
'[class.ng-untouched]': 'is("untouched")',
'[class.ng-touched]': 'is("touched")',
...
};
and also a new is
function:
is(status: string): boolean {
return this._cd?.control?.[status] ?? false;
}
What do you think?
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.
Yeah I like that.
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.
Sorry for the intrusion but why not get rid of null coalescing and do it like this:
is(status: string): boolean {
// or Boolean(...)
return !!this._cd?.control?.[status];
}
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.
@dev054, agree, we can do that too.
…trolStatusGroup` directive
…tusGroup` directive (#40344) The `NgControlStatusGroup` directive is shared between template-driven and reactive form modules. In cases when only reactive forms module is present, the `NgControlStatusGroup` directive is still activated on all `<form>` elements, but if there is no other reactive directive applied (such as `formGroup`), corresponding `ControlContainer` token is missing, thus causing exceptions (since `NgControlStatusGroup` directive relies on it to determine the status). This commit updates the logic to handle the case when no `ControlContainer` is present (effectively making directive logic a noop in this case). Alternative approach (more risky) worth considering in the future is to split the `NgControlStatusGroup` into 2 directives with different set of selectors and include them into template-driven and reactive modules separately. The downside is that these directives might be activated simultaneously on the same element (e.g. `<form>`), effectively doing the work twice. Resolves #38391. PR Close #40344
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. |
The
NgControlStatusGroup
directive is shared between template-driven and reactive form modules. In cases whenonly reactive forms module is present, the
NgControlStatusGroup
directive is still activated on all<form>
elements, but if there is no other reactive directive applied (such as
formGroup
), correspondingControlContainer
token is missing, thus causing exceptions (since
NgControlStatusGroup
directive relies on it to determine thestatus). This commit updates the logic to handle the case when no
ControlContainer
is present (effectively makingdirective logic a noop in this case).
Alternative approach (more risky) worth considering in the future is to split the
NgControlStatusGroup
into2 directives with different set of selectors and include them into template-driven and reactive modules separately.
The downside is that these directives might be activated simultaneously on the same element (e.g.
<form>
),effectively doing the work twice.
Resolves #38391.
PR Type
What kind of change does this PR introduce?
Does this PR introduce a breaking change?