Skip to content

Commit

Permalink
fix(forms): Make NgControlStatus host bindings OnPush compatible (#…
Browse files Browse the repository at this point in the history
…55720)

This commit makes the host bindings of `NgControlStatus[Group]`
compatible with `OnPush` components. Note that this intentionally _does not_
expose any new APIs in the forms module. The goal is only to remove
unpreventable `ExpressionChangedAfterItHasBeenCheckedError` in the forms
code that developers do not have control over.

PR Close #55720
  • Loading branch information
atscott authored and AndrewKushnir committed Jun 18, 2024
1 parent 775f451 commit 00bde8b
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 30 deletions.
10 changes: 5 additions & 5 deletions goldens/public-api/forms/index.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export abstract class AbstractControl<TValue = any, TRawValue extends TValue = T
get parent(): FormGroup | FormArray | null;
abstract patchValue(value: TValue, options?: Object): void;
get pending(): boolean;
readonly pristine: boolean;
get pristine(): boolean;
removeAsyncValidators(validators: AsyncValidatorFn | AsyncValidatorFn[]): void;
removeValidators(validators: ValidatorFn | ValidatorFn[]): void;
abstract reset(value?: TValue, options?: Object): void;
Expand All @@ -88,9 +88,9 @@ export abstract class AbstractControl<TValue = any, TRawValue extends TValue = T
setParent(parent: FormGroup | FormArray | null): void;
setValidators(validators: ValidatorFn | ValidatorFn[] | null): void;
abstract setValue(value: TRawValue, options?: Object): void;
readonly status: FormControlStatus;
get status(): FormControlStatus;
readonly statusChanges: Observable<FormControlStatus>;
readonly touched: boolean;
get touched(): boolean;
get untouched(): boolean;
get updateOn(): FormHooks;
updateValueAndValidity(opts?: {
Expand Down Expand Up @@ -505,7 +505,7 @@ export class FormGroupDirective extends ControlContainer implements Form, OnChan
removeFormArray(dir: FormArrayName): void;
removeFormGroup(dir: FormGroupName): void;
resetForm(value?: any): void;
readonly submitted: boolean;
get submitted(): boolean;
updateModel(dir: FormControlName, value: any): void;
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<FormGroupDirective, "[formGroup]", ["ngForm"], { "form": { "alias": "formGroup"; "required": false; }; }, { "ngSubmit": "ngSubmit"; }, never, never, false, never>;
Expand Down Expand Up @@ -702,7 +702,7 @@ export class NgForm extends ControlContainer implements Form, AfterViewInit {
setValue(value: {
[key: string]: any;
}): void;
readonly submitted: boolean;
get submitted(): boolean;
updateModel(dir: NgControl, value: any): void;
// (undocumented)
static ɵdir: i0.ɵɵDirectiveDeclaration<NgForm, "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", ["ngForm"], { "options": { "alias": "ngFormOptions"; "required": false; }; }, { "ngSubmit": "ngSubmit"; }, never, never, false, never>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@
{
"name": "COMPOSITION_BUFFER_MODE"
},
{
"name": "COMPUTED_NODE"
},
{
"name": "COMPUTING"
},
{
"name": "CONTAINER_HEADER_OFFSET"
},
Expand Down Expand Up @@ -197,6 +203,9 @@
{
"name": "ENVIRONMENT_INITIALIZER"
},
{
"name": "ERRORED"
},
{
"name": "EVENT_MANAGER_PLUGINS"
},
Expand Down Expand Up @@ -524,6 +533,9 @@
{
"name": "SIGNAL"
},
{
"name": "SIGNAL_NODE"
},
{
"name": "SIMPLE_CHANGES_STORE"
},
Expand Down Expand Up @@ -593,6 +605,9 @@
{
"name": "TouchedChangeEvent"
},
{
"name": "UNSET"
},
{
"name": "USE_VALUE"
},
Expand Down Expand Up @@ -770,6 +785,9 @@
{
"name": "assertControlPresent"
},
{
"name": "assertProducerNode"
},
{
"name": "attachInjectFlag"
},
Expand Down Expand Up @@ -842,6 +860,9 @@
{
"name": "computeStaticStyling"
},
{
"name": "computed"
},
{
"name": "concatStringsWithSpace"
},
Expand All @@ -851,6 +872,9 @@
{
"name": "configureViewWithDirective"
},
{
"name": "consumerAfterComputation"
},
{
"name": "consumerBeforeComputation"
},
Expand All @@ -860,6 +884,9 @@
{
"name": "consumerIsLive"
},
{
"name": "consumerMarkDirty"
},
{
"name": "consumerPollProducersForChange"
},
Expand Down Expand Up @@ -917,6 +944,9 @@
{
"name": "createOperatorSubscriber"
},
{
"name": "createPlatform"
},
{
"name": "createPlatformFactory"
},
Expand All @@ -929,6 +959,9 @@
{
"name": "deepForEachProvider"
},
{
"name": "defaultEquals"
},
{
"name": "defaultIterableDiffersFactory"
},
Expand Down Expand Up @@ -1244,6 +1277,9 @@
{
"name": "importProvidersFrom"
},
{
"name": "inNotificationPhase"
},
{
"name": "includeViewProviders"
},
Expand Down Expand Up @@ -1331,6 +1367,9 @@
{
"name": "isComponentHost"
},
{
"name": "isConsumerNode"
},
{
"name": "isContentQueryHost"
},
Expand Down Expand Up @@ -1484,6 +1523,9 @@
{
"name": "markViewForRefresh"
},
{
"name": "markedFeatures"
},
{
"name": "maybeUnwrapEmpty"
},
Expand Down Expand Up @@ -1577,6 +1619,9 @@
{
"name": "parseAndConvertBindingsForDefinition"
},
{
"name": "performanceMarkFeature"
},
{
"name": "pickAsyncValidators"
},
Expand All @@ -1589,15 +1634,30 @@
{
"name": "platformCore"
},
{
"name": "postSignalSetFn"
},
{
"name": "processInjectorTypesWithProviders"
},
{
"name": "producerAccessed"
},
{
"name": "producerAddLiveConsumer"
},
{
"name": "producerNotifyConsumers"
},
{
"name": "producerRemoveLiveConsumerAtIndex"
},
{
"name": "producerUpdateValueVersion"
},
{
"name": "producerUpdatesAllowed"
},
{
"name": "profiler"
},
Expand Down Expand Up @@ -1754,6 +1814,15 @@
{
"name": "shouldSearchParent"
},
{
"name": "signal"
},
{
"name": "signalAsReadonlyFn"
},
{
"name": "signalSetFn"
},
{
"name": "storeLViewOnDestroy"
},
Expand All @@ -1763,6 +1832,12 @@
{
"name": "stringifyCSSSelector"
},
{
"name": "throwInvalidWriteToSignalError"
},
{
"name": "throwInvalidWriteToSignalErrorFn"
},
{
"name": "throwProviderNotFoundError"
},
Expand All @@ -1787,6 +1862,9 @@
{
"name": "uniqueIdCounter"
},
{
"name": "untracked"
},
{
"name": "unwrapRNode"
},
Expand Down
Loading

0 comments on commit 00bde8b

Please sign in to comment.