-
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
Deferred trigger prerequisite refactors #51816
Conversation
…gers Updates the parsing for `interaction` and `hover` triggers to require a reference to an element.
When the `TargetBinder` was written, the only embedded-view-based nodes were templates, but now we have `{#if}`, `{#switch}` and `{#defer}` which have similar semantics. These changes rework the binder to account for the new nodes.
… element Adds a utility to the `BoundTarget` that helps with resolving which element a deferred block is pointing to. We need a separate method for this, because deferred blocks have some special logic for where the trigger can be located.
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.
@crisbeto looks great 👍
// Use the `Scope` to extract the entities present at every level of the template. | ||
const templateEntities = extractTemplateEntities(scope); | ||
const scopedNodeEntities = extractScopedNodeEntities(scope); |
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.
nit:
const scopedNodeEntities = extractScopedNodeEntities(scope); | |
const scopedNodeEntities = extractScopedNodes(scope); |
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.
I think the current name is more accurate, because we aren't extracting the scoped nodes themselves, but rather entities (e.g. Reference
and Variable
) present in them.
@@ -54,7 +53,7 @@ export class R3TargetBinder<DirectiveT extends DirectiveMeta> implements TargetB | |||
TemplateBinder.applyWithScope(target.template, scope); | |||
return new R3BoundTarget( | |||
target, directives, eagerDirectives, bindings, references, expressions, symbols, | |||
nestingLevel, templateEntities, usedPipes, eagerPipes, deferBlocks); | |||
nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks); |
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.
nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks); | |
nestingLevel, scopedNodes, usedPipes, eagerPipes, deferBlocks); |
} else if ( | ||
nodeOrNodes instanceof DeferredBlock || nodeOrNodes instanceof DeferredBlockError || | ||
nodeOrNodes instanceof DeferredBlockPlaceholder || | ||
nodeOrNodes instanceof DeferredBlockLoading) { |
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.
Since we use this check in a couple places, it'd be great to extract it to a separate fn:
} else if ( | |
nodeOrNodes instanceof DeferredBlock || nodeOrNodes instanceof DeferredBlockError || | |
nodeOrNodes instanceof DeferredBlockPlaceholder || | |
nodeOrNodes instanceof DeferredBlockLoading) { | |
} else if (isScopedNode(nodeOrNodes)) { |
We can check all node types there (including IfBlockBranch
and ForLoopBlock
), so we can do do type narrowing too:
function isScopedNode(node: unknown): node is ScopedNode { ... }
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.
I agree that this felt a bit weird when I was writing it, but there are a couple of reasons why I think we should keep it:
- Once template type checking is implemented for control flow, there will be different handling for each
ScopedNode
, with the exception of the deferred ones. - Using the
if
/else if
like we do here will result in an error whenever we add a node type toScopedNode
, which is good because it makes it easier to see where we need to adjust the logic. In comparison, if we do something like following we won't get such an error:
if (!isScopedNode(node)) {
return ...;
}
if (node instanceof IfBlock) {
...
} else if (node instanceof DeferredBlock) {
...
}
This PR was merged into the repository by commit d538908. |
When the `TargetBinder` was written, the only embedded-view-based nodes were templates, but now we have `{#if}`, `{#switch}` and `{#defer}` which have similar semantics. These changes rework the binder to account for the new nodes. PR Close #51816
Reworks the compiler to use the API introduced in angular#51816 to match triggers to the element nodes they point to. This will be used to generate the new instructions for `on interaction` and `prefetch on interaction`.
Reworks the compiler to use the API introduced in angular#51816 to match triggers to the element nodes they point to. This will be used to generate the new instructions for `on interaction` and `prefetch on interaction`.
Reworks the compiler to use the API introduced in angular#51816 to match triggers to the element nodes they point to. This will be used to generate the new instructions for `on interaction` and `prefetch on interaction`.
Reworks the compiler to use the API introduced in angular#51816 to match triggers to the element nodes they point to. This will be used to generate the new instructions for `on interaction` and `prefetch on interaction`.
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. |
…gers (angular#51816) Updates the parsing for `interaction` and `hover` triggers to require a reference to an element. PR Close angular#51816
…ar#51816) When the `TargetBinder` was written, the only embedded-view-based nodes were templates, but now we have `{#if}`, `{#switch}` and `{#defer}` which have similar semantics. These changes rework the binder to account for the new nodes. PR Close angular#51816
… element (angular#51816) Adds a utility to the `BoundTarget` that helps with resolving which element a deferred block is pointing to. We need a separate method for this, because deferred blocks have some special logic for where the trigger can be located. PR Close angular#51816
These changes include some refactors to facilitate the implementation of the
viewport
,interaction
andhover
triggers. The majority of the changes is around reworking theR3TargetBinder
to considerif
,switch
anddefer
blocks (plus the sub-blocks) as separate embedded views. This allows us to properly resolve references within their scope and is consistent with how they behave at runtime. Split up across the following commits to make it easier to review:refactor(compiler): require a reference in interaction and hover triggers
Updates the parsing for
interaction
andhover
triggers to require a reference to an element.refactor(compiler): update binder to account for new semantics
When the
TargetBinder
was written, the only embedded-view-based nodes were templates, but now we have{#if}
,{#switch}
and{#defer}
which have similar semantics. These changes rework the binder to account for the new nodes.refactor(compiler): add utility to resolve the deferred block trigger element
Adds a utility to the
BoundTarget
that helps with resolving which element a deferred block is pointing to. We need a separate method for this, because deferred blocks have some special logic for where the trigger can be located.