2649 Commits

Author SHA1 Message Date
Andrew Scott 744e20641a fix(core): Fix possible infinite loop with markForCheck by partially reverting #54074 (#54329)
In some situations, calling `markForCheck` can result in an infinite
loop in seemingly valid scenarios. When a transplanted view is inserted
before its declaration, it gets refreshed in the retry loop of
`detectChanges`. At this point, the `Dirty` flag has been cleared from
all parents. Calling `markForCheck` marks the insertion tree up to the
root `Dirty`. If the declaration is checked again as a result (i.e.
because it has default change detection) and is reachable because its
parent was marked `Dirty`, this can cause an infinite loop. The
declaration is refreshed again, so the insertion is marked for refresh
(again). We enter an infinite loop if the insertion tree always calls
`markForCheck` for some reason (i.e. `{{createReplayObservable() | async}}`).

While the case above does fall into an infinite loop, it also truly is a
problem in the application. While it's not an infinite synchronous loop,
the declaration and insertion are infinitely dirty and will be refreshed
on every change detection round.

Usually `markForCheck` does not have this problem because the `Dirty`
flag is not cleared until the very end of change detection. However, if
the view did not already have the `Dirty` flag set, it is never cleared
because we never entered view refresh. One solution to this problem
could be to clear the `Dirty` flag even after skipping view refresh but
traversing to children.

PR Close #54329
2024-02-08 16:45:21 +00:00
Paul Gschwendtner a42f0ba65e refactor(core): separate InputSignal and InputSignalWithTransform (#54233)
This commit separates `InputSignal` for input signals with transforms.
The reason being that most of the time, signal inputs are not using
transforms and the generics are rather confusing.

Especially for users with inferred types displayed in their IDEs, the
input signal types are seemingly complex, even if no transform is used.

For this reason, we are introducing a new type called
`InputSignalWithTransform`. This type will be used for inputs with
transforms, while non-transform inputs just use `InputSignal`.

A notable fact is that `InputSignal` extends `InputSignalWithTransform`,
with the "identity transform". i.e. there is no transform. This allows
us to share the code for input signals. In practice, we don't expect
users to pass around `InputSignal`'s anyway.

PR Close #54233
2024-02-05 15:06:49 +00:00
Andrew Scott 54deaae3ba test(core): ExpressionChanged... error does not happen with signals (#54206)
This test ensures that the `ExpressionChanged...` error does not happen
when signals are updated in a view that is attached to `ApplicationRef`
but was already checked. This was fixed in 432afd1ef4
which actually consequently fixes it for regular `markForCheck` as well.

PR Close #54206
2024-02-02 14:51:46 +00:00
Mateusz Daniluk 52a31d0ed8 refactor: standardize doctype declaration to <!DOCTYPE html> (#51052)
This commit standardizes the doctype declaration across all HTML files in the project to use `<!DOCTYPE html>`

PR Close #51052
2024-02-01 19:29:46 +00:00
Andrew Scott 7df133dcc2 fix(core): afterRender hooks should allow updating state (#54074)
It was always the intent to have `afterRender` hooks allow updating
state, as long as those state updates specifically mark views for
(re)check. This commit delivers that behavior. Developers can now use
`afterRender` hooks to perform further updates within the same change
detection cycle rather than needing to defer this work to another round
(i.e. `queueMicrotask(() => <<updateState>>)`). This is an important
change to support migrating from the `queueMicrotask`-style deferred
updates, which are not entirely compatible with zoneless or event `NgZone` run
coalescing.

When using a microtask to update state after a render, it
doesn't work with coalescing because the render may not have happened
yet (coalescing and zoneless use `requestAnimationFrame` while the
default for `NgZone` is effectively a microtask-based change detection
scheduler). Second, when using a `microtask` _during_ change detection to defer
updates to the next cycle, this can cause updates to be split across
multiple frames with run coalescing and with zoneless (again, because of
`requestAnimationFrame`/`macrotask` change detection scheduling).

PR Close #54074
2024-01-31 20:19:07 +00:00
Matthieu Riegler 413db303f4 refactor(forms): Provide RadioControlRegistry in root. (#54130)
The `RadioControlRegistry` was only provided in a module, providedIn: 'root' fixes that issue.

Fixes #54117

Co-authored-by: sr5434 <118690585+sr5434@users.noreply.github.com>

PR Close #54130
2024-01-31 14:55:57 +00:00
Andrew Scott c5a0e909ac refactor(core): Update ComponentFixture behavior when using zoneless scheduler (#54024)
When the zoneless scheduler is provided, we want to update the behavior
of `ComponentFixture` to address common issues and painpoints in testing.
Developers should never have to call `detectChanges` on a fixture
manually. Instead of calling `detectChanges` after performing an
action that updates state and requies a template refresh, developers
should wait for change detection to run because the update needs to also have
notified the scheduler. If this was not the case, the component would
not work correctly in the application. Calling `detectChanges` to force
an update could hide real bugs.

This commit also updates the zoneless tests to uses `ComponentFixture`
instead of manually attaching to the `ApplicationRef` and rewriting a
lot of the helpers (`getDebugNode`, `isStable` as a value, `whenStable` as a
Promise).

PR Close #54024
2024-01-29 20:21:48 +00:00
cexbrayat c477e876e3 fix(core): change defer block fixture default behavior to playthrough (#54088)
This is a followup to #53956

The default behavior needs to be changed in `TestBedCompiler` as well to have an effect.

PR Close #54088
2024-01-26 15:44:40 +00:00
Andrew Scott f222bee8fa fix(router): revert commit that replaced last helper with native Array.at(-1) (#54021)
While `Array.at` is technically supported in all browsers we officially
support, the change was needlessly breaking without any real benefit.

PR Close #54021
2024-01-24 10:54:55 +01:00
Younes Jaaidi 5f9cac037b test(core): fix test with false-negative risk (#54025)
change assertion to handle the case where the function doesn't throw

PR Close #54025
2024-01-23 16:58:57 +01:00
Joey Perrott 1f6c96a1dc refactor: migrate animations to prettier formatting (#53977)
Migrate formatting to prettier for animations from clang-format

PR Close #53977
2024-01-19 20:08:58 +01:00
Andrew Scott 7620f506c0 refactor(core): node removal notifies scheduler only when animations are enabled (#53857)
Node removal is immediate and does not require change detection to run
when animations are not provided. This refactor makes the animation
engine notify the scheduler rather than doing it on all node removals.

PR Close #53857
2024-01-19 10:28:25 +01:00
Dylan Hunn be882c3efb Revert "refactor(core): improve forwardRef typings (#53880)"
This reverts commit af6f6e6448.
2024-01-17 13:57:11 -08:00
Jessica Janiuk 6f79507ea7 fix(core): Change defer block fixture default behavior to playthrough (#53956)
This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: #53686

PR Close #53956
2024-01-17 10:45:42 -08:00
Pawel Kozlowski 1112e9196a refactor(core): re-organize queries code (#53922)
This commit splits the query implementation and instructions
into a separate files. This is a pattern frequently used by
other functional areas of the framework and is a preparation for
introducing queries-as-signals where we are going to see more
instructions delegating to the same core functionality.

PR Close #53922
2024-01-16 16:00:36 -08:00
Pawel Kozlowski d7c75c6edb refactor(core): improve forwardRef typings (#53880)
This commit improves the forwardRef typings for better
type safety and inference.

PR Close #53880
2024-01-12 10:26:02 -08:00
Andrew Scott 0daca457bb fix(core): TestBed should still use the microtask queue to schedule effects (#53843)
Prior to this commit, `TestBed` would require tests call `flushEffects`
or `fixture.detectChanges` in order to execute effects. In general, we
want to discourage authoring tests like this because it makes the timing
of change detection and effects differ from what happens in the
application. Instead, developers should perform actions and `await` (or
`flush`/`tick` when using `fakeAsync`) some `Promise` so that Angular
can react to the changes in the same way that it does in the
application.

Note that this still _allows_ developers to flush effects synchronously
with `flushEffects` and `detectChanges` but also enables the <action>,
`await` pattern described above.

PR Close #53843
2024-01-11 12:05:58 -08:00
Paul Gschwendtner 863be4b698 feat(core): expose new input API for signal-based inputs (#53872)
Enables signal inputs for existing Zone based components.
This is a next step we are taking to bring signal inputs earlier to the Angular community.

The goal is to enable early access for the ecosystem to signal inputs, while we are continuing
development of full signal components as outlined in the RFC. This will allow the ecosystem
to start integrating signals more deeply, prepare for future migrations, and improves code quality
and DX for existing components (especially for OnPush).

Based on our work on full signal components, we've gathered more information and learned
new things. We've improved the API by introducing a way to intuitively declare required inputs,
as well as improved the API around initial values. We even support non-primitive initial values
as the first argument to the `input` function now.

```ts
@Directive({..})
export class MyDir {
  firstName = input<string>();            // string|undefined
  lastName = input.required<string>();    // string
  age = input(0);                         // number
```

PR Close #53872
2024-01-10 12:33:31 -08:00
Paul Gschwendtner b2066d4922 refactor(compiler-cli): detect input functions without partial evaluation (#53872)
This allows us to ensure signal inputs and a potential JIT transform
remain single file compilation compatible. The consequences are that
options need to be statically analyzable more strictly, compared to
loosened restrictions with static interpretation where e.g. `alias`
can be defined through a shared variable.

PR Close #53872
2024-01-10 12:33:31 -08:00
Paul Gschwendtner 7862686a60 test(core): add acceptance unit tests for signal inputs (#53808)
Adds AOT and JIT unit tests for signal inputs that verify integration of
signal inputs for our users.

PR Close #53808
2024-01-10 12:21:06 +00:00
Paul Gschwendtner 74099a3d4a test: add infrastructure to run signal acceptance tests with JIT and AOT (#53808)
Adds infrastructure to run signal input tests with JIT (using the
transform) and AOT. Acceptance tests for signal inputs will run with
both variants. In the future we can consider expanding this
infrastructure for all of our acceptance tests, but that's a different
story.

PR Close #53808
2024-01-10 12:21:06 +00:00
Paul Gschwendtner 55b202f0c7 test(core): add test playground for zone signal inputs (#53808)
This commit creates a small http server Angular application playground
for playing with signal inputs. This is useful for development and also
validates some of the common input patterns.

PR Close #53808
2024-01-10 12:21:05 +00:00
Paul Gschwendtner 977884a0c8 test(core): add runtime tests for input signal (#53808)
This commit adds some runtime unit tests to ensure that input
signal is behaving properly at runtime.

PR Close #53808
2024-01-10 12:21:05 +00:00
Paul Gschwendtner cfab5a59d6 refactor(core): detect signal input transforms independently of flag (#53808)
This commit changes the `HasTransform` flag to be only concerned with
decorator inputs. This allows us to automatically detect signal input
transforms without reliance on the flag, resulting in less complexity in
the compiler (as outlined in the design doc) and various  other places,
while it also allows us to simplify JIT support for signal inputs
because there would be no need to capture the "hasTransform" state in
the decorator so that JIT can generate the according input flags.

`isSignal` will still persist as an input flag to allow for monomorphic
and highly efficient distinguishing at runtime, whether an input is
signal based or not. JIT transform will also need to propagate this
information to the runtime somehow.

PR Close #53808
2024-01-10 12:21:04 +00:00
Andrew Scott 5978b3d132 refactor(core): Move change detection scheduler implementation to core (#53579)
This commit moves the implementation of the change detection scheduler
used for testing to angular/core along with a (private export) provider function.

Note: Naming of the provider function is absolutely not final (and not
public API). I would prefer one that did not mention "zones"
but the easiest thing for now is to have a "Zone" and "Zoneless" naming
scheme.

PR Close #53579
2024-01-09 16:05:32 -08:00
Andrew Scott 60dfcc209e test(core): Add scheduler in tests to tie into ApplicationRef.isStable (#53579)
This commit updates the test scheduler implementation to contribute to
ApplicationRef stableness.

PR Close #53579
2024-01-09 16:05:31 -08:00
Andrew Scott c2dd703d2f refactor(core): Remove internal-only testability features (#53767)
This commit removes the testability features that are internal only.
This simplifies the implementation of testability which will need
updates to support zoneless. Those updates will be easier to manage if
the Testability implementation is simpler.
While protractor is indeed officially EOL, we will still need to do some
updates to support teams migrating to zoneless that have protractor
tests.

As far as protractor's own use of `whenStable`, it does not read the
internal only methods either:
https://github.com/angular/protractor/blob/master/lib/clientsidescripts.js
Anything else depending on these values are not following the defined public API
contract.

PR Close #53767
2024-01-09 14:46:46 -08:00
Kristiyan Kostadinov 2dedc4a969 fix(compiler): generate less code for advance instructions (#53845)
We generate `advance` instructions before most update instructions and the majority of `advance` calls are advancing by one. We can save some bytes for the most common case by omitting the parameter for `advance(1)` altogether.

PR Close #53845
2024-01-09 12:27:58 -08:00
Tomasz Ducin 2d7d4e2cf0 refactor(core): type-safe global ng (#53439)
This PR provides strict type definition for the window.ng object used
for both console debugging and devtools. `GlobalDevModeUtils` now
gathers all type information about all methods exposed on window.ng.

PR Close #53439
2024-01-09 12:17:48 -08:00
Andrew Scott e2b598852f refactor(core): node removal should notify the scheduler (#53812)
This commit ensures that change detection runs when an `LView` is
removed. Change detection is required because DOM nodes aren't actually
removed until the animation engine flushes and this doesn't happen until
the end of `detectChangesInternal` (`rendererFactory.end`).

PR Close #53812
2024-01-09 08:51:30 -08:00
Andrew Scott dfcf0d5882 fix(core): afterRender hooks now only run on ApplicationRef.tick (#52455)
The `afterRender` hooks currently run after `ApplicationRef.tick` but
also run after any call to `ChangeDetectorRef.detectChanges`. This is
problematic because code which uses `afterRender` cannot expect the
component it's registered from to be rendered when the callback
executes. If there is a call to `ChangeDetectorRef.detectChanges` before
the global change detection, that will cause the hooks to run earlier
than expected.

This behavior is somewhat of a blocker for the zoneless project. There
is plenty of application code that do things like `setTimeout(() =>
doSomethingThatExpectsComponentToBeRendered())`, `NgZone.onStable(() =>
...)` or `ApplicationRef.onStable...`. `ApplicationRef.onStable` is a
should likely work similarly, but all of these are really wanting an API
that is `afterRender` with the requirement that the hook runs after the
global render, not an individual CDRef instance.

This change updates the `afterRender` hooks to only run when
`ApplicationRef.tick` happens.

fixes #52429
fixes #53232

PR Close #52455
2024-01-08 11:30:27 -08:00
Matthieu Riegler 5e84d9c8c3 refactor(router): replace last helper with native Array.at(-1) (#53749)
We now have a native method to return the last item of an array

PR Close #53749
2024-01-04 13:58:17 -08:00
Andrew Scott f4bd5a33d2 fix(platform-server): Do not delete global Event (#53659)
This commit removes a hack that deletes `Event` from the global context
when using domino. Instead, it sets the global event to domino's
implementation of `Event`.

PR Close #53659
2024-01-04 12:51:22 -08:00
Paul Gschwendtner 4e2f0b7f0d test(core): add type signature test for signal input API (#53571)
Adds tests that allow us to ensure that the `input` API works as
expected and that resulting return types match our expectations- without
silently regressing in the future, or missing potential edge-cases.

Testing signatures is hard because of covariance and contravariance,
especially when it comes to the different semantics of `ReadT` and
`WriteT` of input signals. We enable reliable testing by validating the
`d.ts` of the "fake directive class". This ensures clear results,
compared to relying on e.g. type assertions that might
accidentally/silently pass due to covariance/contravariance or
biavariance in the type system.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner 1d95a832e3 refactor(core): detect signal inputs at runtime using input flags (#53571)
This commit introduces a new enum for capturing additional metadata
about inputs. Called `InputFlags`. These will be built up at compile
time and then propagated into the runtime logic, in a way that does
not require additional lookup dictionaries data structures, or
additional memory allocations for "common inputs" that do not have any flags.

The flags will incorporate information on whether an input is signal
based. This can then be used to avoid megamorphic accesses when such
input is set- as we'd not need to check the input field value. This also
avoids cases where an input signal may be used as initial value for an
input (as we'd not incorrectly detect the input as a signal input then).

The new metadata emit will be useful for incorporating additional
metadata for inputs, such as whether they are required etc (although
required inputs are a build-time only construct right now- but this is a
good illustration of why input flags can be useful). An alternative
could have been to have an additional boolean entry for signal inputs,
but allocating a number with more flexible input flags seems more future
proof and more reasonable andreadable.

More information on the megamorphic access when updating an input
signal
https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner 32f908ab70 fix(core): do not accidentally inherit input transforms when overridden (#53571)
Currently when a base class defines an input with a transform, derived
classes re-defining the input via `@Input`, or `inputs: [<..>]`, end up
inherting the transform due to a bug in the inherit definitions feature.

This commit fixes this. We verified in the Google codebase that this is
an unlikely occurrence and it's trivial to fix on user side by removing
the re-declaration/override, or explictly adding the necessary
transform.

Conceptually, the behavior was quite inconsistent as everything else of
inputs was overridden as expected. i.e. alias, required state etc. The
exception were input transforms. This commit fixes this.

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner 560ae24511 refactor(core): initial test code for setInput to work with input signals (#53571)
At this point, we have the following pieces in place:

* the input signature is implemented
* the compiler properly parses and recognizes signal inputs
* the compiler supports type-checking of signal inputs
* input signal metadata is passed to partial output

This commit adds a naive runtime solution to distinguishing between
signal inputs and decorator inputs when the `property` instruction
invokes. This is not ideal and non-performant as we introduce additional
megamorphic reads for every property instruction invocation, or if we'd
use `instanceof`, introducing a hard dependency on `InputSignal` and
risking potentially slower detection.

This code exists purely for testing, to enable playing with input
signals in the playground. In a future commit, we will pass around the
input signal metadata at runtime and can perform highly optimized checks
to distinguish between signal or non-signal inputs- when assigning
values.

More information: https://docs.google.com/document/d/1FpnFruviKb6BFTQfMAP2AMEqEB0FI7z-3mT_qm7lzX8/edit#heading=h.oloxympe902x

PR Close #53571
2024-01-04 12:07:13 -08:00
Paul Gschwendtner 7fb4a37f7d refactor(core): introduce runtime InputSignal implementation (#53571)
This commit introduces the runtime `InputSignal` implementation.
Input initializers using `input` or `input.required` will result in
an instance of `InputSignal` to be created.

An input signal extends the signal primtive, with a couple of small
differences:

 - it's a readonly signal. There is no public `set` or `update`.
 - equality is non-configurable. As per CD semantics, the value is
   guaranteed to be different when the `property` instruction attempts
   to update an input signal.
 - we support a `transform` function, that allows transforming input
   values. The transform is called whenever the input is set. An
   alternative could have been to follow computed-semantics and call the
   transform upon accessing, if dirty.

In the future, we might change this to extend the computed reactive
node, so that we can support computed inputs that do not rely on
continious bound value assignments. See signal based components RFC.

PR Close #53571
2024-01-04 12:07:13 -08:00
Kristiyan Kostadinov 2b9a850789 fix(core): allow effect to be used inside an ErrorHandler (#53713)
`effect` was expecting an `ErrorHandler` in its constructor which can lead to a circular DI error if an effect is used inside a custom `ErrorHandler`. These changes inject the `ErrorHandler` only when reporting errors.

Fixes #52680.

PR Close #53713
2024-01-03 10:17:30 -08:00
Andrew Scott 8d58595478 refactor(core): Add scheduler abstraction and notify when necessary (#53499)
In order to provide a reasonable experience for Angular without Zones,
we need a mechanism to run change detection when we receive a change
notification. There are several existing APIs today that serve as the
change notification: `ChangeDetectorRef.markForCheck`, signal updates,
event listeners (since they mark the view dirty), and attaching a view to
either the `ApplicationRef` or `ChangeDetectorRef`. These operations
are now paired with a notification to the change detection scheduler.

The concrete implementation for this scheduler is still being designed.
However, this gives us a starting point to partner with teams to
experiment with what that might look like.

PR Close #53499
2023-12-20 07:53:31 -08:00
Andrew Scott 12181b9914 refactor(core): Use single source of truth for ApplicationRef.isStable (#53576)
This commit updates the `ApplicationRef.isStable` implementation to use
a single `Observable` to manage the state. This simplifies the mental
model quite a bit and removes the need for rx operators like
`distinctUntilChanged` and `combineLatest`.

PR Close #53576
2023-12-19 12:42:45 -08:00
Andrew Scott c16e9a7cf0 refactor(core): No default for zone stableness token (#53505)
When an application does not use zones, it does not need a default value
for the zone stableness token. This will allow zoneless applications to
tree-shake a lot of rxjs operators out of `ApplicationRef`.

Note that at the moment, `provideZoneChangeDetection` is included in all
applications as well as the `TestBed` environment. It is not currently
possible to remove the zone stable code as a result. This will be
possible only when we make zones an opt-in rather than opt-out.

PR Close #53505
2023-12-19 09:59:12 -08:00
Kristiyan Kostadinov df8a825910 fix(compiler): project empty block root node (#53620)
Expands the workaround from #52414 to allow for the root nodes of `@empty` blocks to be content projected.

Fixes #53570.

PR Close #53620
2023-12-19 08:37:33 -08:00
Andrew Scott 6c8faaa769 refactor(core): Rename InitialRenderPendingTasks and restructure isStable observable (#53534)
The InitialRenderPendingTasks currently attempts to only contribute to
ApplicationRef stableness one time to support SSR. This isn't actually
how the switchMap works in reality. This commit updates
the isStable observable to be more clear that it's always a combination
of the zone stableness and pending tasks.

In addition, this commit renames the service to just be PendingTasks
because it doesn't directly relate to rendering. While the purpose is
to track things that might cause rendering to happen, we don't know if the
tasks will affect rendering at all.

PR Close #53534
2023-12-19 08:36:28 -08:00
Kristiyan Kostadinov 872e7f25fe fix(core): tree shake version class (#53598)
Core bundles were retaining the `Version` class and `VERSION` constant, because we stamp out the current version in the DOM. This shouldn't be necessary, because any usage of `0.0.0-PLACEHOLDER` will be replaced with the current version at build time. These changes remove the reference so it can be tree shaken away.

PR Close #53598
2023-12-18 16:26:36 +00:00
Charles Lyding e149ebf228 build: update rxjs build version to v7 (#53500)
The version of rxjs used to build the repository has been updated to v7.
This required only minimal changes to the code. Most of which were type
related only due to more strict types in v7. The behavior in those cases
was left intact. The most common type related change was to handle the
possibility of `undefined` with `toPromise` which was always possible with
v6 but the types did not reflect the runtime behavior. The one change that
was not type related was to provide a parameter value to the `defaultIfEmpty`
operator. It no longer defaults to a value of `null` if no default is provided.
To provide the same behavior the value of `null` is now passed to the operator.

PR Close #53500
2023-12-18 16:25:37 +00:00
Matthieu Riegler d7e7409e81 refactor(animations): drop convertToMap & copyStyles and use native functions. (#52441)
`copyStyles` was side-effectful and also returned a value : not great.

PR Close #52441
2023-12-14 12:33:24 -08:00
Matthieu Riegler d28ce0a4cf refactor(animations): use a spread operator instead of custom copyObj (#52441)
Using the spread operator is the fastest way to shallow copy an object.

PR Close #52441
2023-12-14 12:33:24 -08:00
Matthieu Riegler 6a347d36eb refactor(animations): use a spread operator to convert an iterable to an array. (#52441)
Using the spread operator is the fastest way to convert an iterable to an array.

PR Close #52441
2023-12-14 12:33:24 -08:00
Andrew Scott 606de5166e refactor(core): newly created and any dirty views should get refreshed during CD (#53022)
When a view has the `Dirty` flag and is reattached, we should ensure that it is
reached and refreshed during the next change detection run from above.

In addition, when a view is created and attached, we should ensure that it is reached
and refreshed during change detection. This can happen if the view is
created and attached outside a change run or when it is created and
attached after its insertion view was already checked. In both cases, we
should ensure that the view is reached and refreshed during either the
current change detection or the next one (if change detection is not
already running).

We can achieve this by creating all views with the `Dirty` flag set.

However, this does happen to be a breaking change in some scenarios.
The one identified internally was actually depending on change detection
_not_ running immediately because it relied on an input value that was
set using `ngModel`. Because `ngModel` sets its value in a `Promise`, it
is not available until the _next_ change detection cycle. Ensuring
created views run in the current change change detection will result in
different behavior in this case.

Making option the default is the solution to #52928. That will have to
wait for a major version.

PR Close #53022
2023-12-14 09:17:49 -08:00