Repository navigation
Conversation
The signal forms field-management effect walks the field tree with children(), which materializes every reachable field on its first run. That undoes the lazy field creation from 98c5afd as soon as effects flush: a form over 100 rows without rules goes from 0 to 301 child fields. Add specs that flush effects and assert laziness, plus a triage note with the root cause and fix options. The specs fail until a fix lands. The note is for review and isn't meant to be merged. See also: angular#70627
Member
|
Going to close the PRs as they're won't me merged as is. Let's move the discussions to the issues. |
4 of 6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Issue #70627 | Triage note | Failing specs | Earlier fix #70633 (closed)
Why the change
This adds failing specs showing that the field cleanup sweep creates every field of a signal form on its first run, so that we can agree on the fix before I write it.
Special things to note
markAsTouched()walks children, and Signal forms:required(),min(), and other built-in rules create an injector for every field #71623 shows that every created field with a rule gets its own injector.Change outline
What this PR adds
How the sweep creates every field
Child fields for a form over 100 rows without rules, today:
After the recommended fix:
Recommended fix: the sweep walks only fields that already exist
// packages/forms/signals/src/field/manager.ts private markStructuresLive( structure: FieldNodeStructure, liveStructures: Set<FieldNodeStructure>, ): void { liveStructures.add(structure); - for (const child of structure.children()) { + for (const child of structure.materializedChildren()) { this.markStructuresLive(child.structure, liveStructures); } }A leaf also skips a redundant
childrenMapwrite on everychildren()call:// packages/forms/signals/src/field/structure.ts, class FieldNodeStructure private ensureChildrenMap() { // If we're already materialized, there's nothing to do. - if (this._areChildrenMaterialized()) { + if (this._areChildrenMaterialized() || !isObject(untracked(this.value))) { return; }materializedChildren()still readschildrenMap(), so the sweep reruns when the model changes shape. The control spec removes a row that was read and checks that it's destroyed.markAsTouched(),reloadValidation(), focus, and WebMCP schema inference still callchildren().Alternatives
computeChildrenMap()queues dropped fields, and the effect drains the queuechildren()stop materializingchildren()itselfsubmit()would start untouched. Not recommendedDecisions for maintainers
markAsTouched()andreloadValidation()need the same treatment, and fix(forms): flush debounced descendant values when a field is touched #71150 already starts onmarkAsTouched()._areChildrenMaterialized(),fieldManager.structures, and a spy onchildrenMap.update. Is that acceptable, or would you prefer another check?PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
Does this PR introduce a breaking change?