Skip to content

final form of reset()#68514

Merged
alxhub merged 2 commits into
angular:mainfrom
alxhub:sf/reset-fvc
May 6, 2026
Merged

final form of reset()#68514
alxhub merged 2 commits into
angular:mainfrom
alxhub:sf/reset-fvc

Conversation

@alxhub
Copy link
Copy Markdown
Member

@alxhub alxhub commented May 1, 2026

(see commits)

@ngbot ngbot Bot added this to the Backlog milestone May 1, 2026
@alxhub alxhub force-pushed the sf/reset-fvc branch 4 times, most recently from 18343b2 to a7f15d8 Compare May 1, 2026 23:16
@alxhub alxhub marked this pull request as ready for review May 1, 2026 23:17
@alxhub alxhub added the target: major This PR is targeted for the next major release label May 1, 2026
@pullapprove pullapprove Bot requested review from JeanMeche and devversion May 1, 2026 23:17
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Deployed adev-preview for 49a8295 to: https://ng-dev-previews-fw--pr-angular-angular-68514-adev-prev-ihklxh0u.web.app

Note: As new commits are pushed to this pull request, this link is updated after the preview is rebuilt.

parseErrorsSource.set(parser.errors);
parent.onReset = () => {
parser.reset();
setNativeControlValue(input, parent.state().value());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also set binding['controlValue'] = value like we do for the CVA case?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment thread packages/forms/signals/src/directive/form_field.ts
Comment on lines 374 to 383
controlValue.set = (newValue) => {
set(newValue);
this.markAsDirty();
this.debounceSync();
};
controlValue.update = (updateFn) => {
update(updateFn);
this.markAsDirty();
this.debounceSync();
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to use the signal's equal() function to compare if newValue is different than the current value before calling debounceSync/markAsDirty here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just plain Object.is is fine. We don't specialize equal for controlValue anyway.

Comment thread packages/forms/signals/src/field/structure.ts Outdated
Comment thread packages/forms/src/directives/ng_control.ts Outdated
Comment thread packages/forms/src/directives/ng_control.ts
@alxhub alxhub requested a review from leonsenft May 6, 2026 00:01
Copy link
Copy Markdown
Contributor

@leonsenft leonsenft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

surajy93 and others added 2 commits May 6, 2026 08:35
Synchronize `controlValue` with the model `value` following `reset()`. This
ensures the UI will reflect the form model in cases where a control had a
pending change–delayed by debouncing–at the time it was reset.
Introduce a highly decoupled FVC and CVA custom control reset mechanism, and implement the framework-wide automatic `transformedValue` and native controls clearing bridge for both new Signal Forms and legacy forms (Template-driven and Reactive).

1. Custom Control Reset Propagation (Bug #2):
- Establish agnostic custom control resetting via `FormFieldBindingOptions.reset` in `FormField`.
- Ensure that `FieldNode.reset()` unconditionally triggers `writeValue` updates on CVA custom controls.
- Protect against duplicate writes during subsequent change detection updates in `control_cva.ts` by verifying and tracking previous written values in the local bindings cache.

2. Unified Framework-wide FormControl Integration:
- Introduce a monorepo-wide private InjectionToken `ɵFORM_CONTROL_INTEGRATION` and `ɵFormControlIntegration` interface to act as the single, decoupled bridge for hooking up FVC parse errors and receiving control resets across both Signal and legacy forms architectures.
- Simplify Signal Forms: make `FormField` implements `ɵFormControlIntegration` directly, removing the intermediate context object and reducing DI boilerplate down to a clean `useExisting: FormField` provider. Triggers the `onReset` callback directly inside `FormField.reset()`.
- Upgrade Legacy Forms: `NG_CONTROL_INTEGRATION_PROVIDER` provides the renamed token. `NgControl` handles the event subscription internally (`set onReset(callback)`) to recursively listen to `control.events` (`FormResetEvent`) lazily only when assigned, resolving all `FormControl` swapping timing and lifecycle cleanup races automatically.

3. Automatic `transformedValue` and Native Controls Utility Clearing:
- Make `Parser.reset()` method required in the interface for a cleaner and non-defensive execution.
- Wire `transformedValue` into the new integration token `ɵFORM_CONTROL_INTEGRATION` to clear validation parsing states on resets.
- Lazily resets the UI-facing `rawValue` linked signal utilizing the original native `linkedSignal.set` callback (`originalSet`), correctly bypassing the UI-to-model parser loopback and preventing redundant model writes during `reset()`.
- Wire up Native Controls (`control_native.ts\Device`): Hook `parent.onReset` inside native element creation to automatically trigger the native `parser.reset()` and force DOM writes (`setNativeControlValue`) back down to the DOM input value during resets, ensuring native elements with pending parsing validation errors are successfully cleared and synced on form resets.

TAG=agy
CONV=8b4cee1e-2117-42a4-b242-c8ec7bf01752
@alxhub alxhub modified the milestones: Backlog, v22 candidates May 6, 2026
@alxhub alxhub added action: merge The PR is ready for merge by the caretaker merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note labels May 6, 2026
@alxhub
Copy link
Copy Markdown
Member Author

alxhub commented May 6, 2026

Caretaker: presubmit failures are flakes.

@alxhub alxhub merged commit 849dba6 into angular:main May 6, 2026
19 of 22 checks passed
@alxhub
Copy link
Copy Markdown
Member Author

alxhub commented May 6, 2026

This PR was merged into the repository. The changes were merged into the following branches:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker adev: preview area: forms merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note target: major This PR is targeted for the next major release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants