refactor(ivy): move hostVars
/hostAttrs
from instruction to DirectiveDef
(#34683)
This change moves information from instructions to declarative position: - `ɵɵallocHostVars(vars)` => `DirectiveDef.hostVars` - `ɵɵelementHostAttrs(attrs)` => `DirectiveDef.hostAttrs` When merging directives it is necessary to know about `hostVars` and `hostAttrs`. Before this change the information was stored in the `hostBindings` function. This was problematic, because in order to get to the information the `hostBindings` would have to be executed. In order for `hostBindings` to be executed the directives would have to be instantiated. This means that the directive instantiation would happen before we had knowledge about the `hostAttrs` and as a result the directive could observe in the constructor that not all of the `hostAttrs` have been applied. This further complicates the runtime as we have to apply `hostAttrs` in parts over many invocations. `ɵɵallocHostVars` was unnecessarily complicated because it would have to update the `LView` (and Blueprint) while existing directives are already executing. By moving it out of `hostBindings` function we can access it statically and we can create correct `LView` (and Blueprint) in a single pass. This change only changes how the instructions are generated, but does not change the runtime much. (We cheat by emulating the old behavior by calling `ɵɵallocHostVars` and `ɵɵelementHostAttrs`) Subsequent change will refactor the runtime to take advantage of the static information. PR Close #34683
This commit is contained in:
@ -67,7 +67,7 @@ function baseDirectiveFields(
|
||||
definitionMap.set(
|
||||
'hostBindings', createHostBindingsFunction(
|
||||
meta.host, meta.typeSourceSpan, bindingParser, constantPool,
|
||||
meta.selector || '', meta.name));
|
||||
meta.selector || '', meta.name, definitionMap));
|
||||
|
||||
// e.g 'inputs: {a: 'a'}`
|
||||
definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true));
|
||||
@ -528,8 +528,8 @@ function createViewQueriesFunction(
|
||||
// Return a host binding function or null if one is not necessary.
|
||||
function createHostBindingsFunction(
|
||||
hostBindingsMetadata: R3HostMetadata, typeSourceSpan: ParseSourceSpan,
|
||||
bindingParser: BindingParser, constantPool: ConstantPool, selector: string,
|
||||
name?: string): o.Expression|null {
|
||||
bindingParser: BindingParser, constantPool: ConstantPool, selector: string, name: string,
|
||||
definitionMap: DefinitionMap): o.Expression|null {
|
||||
// Initialize hostVarsCount to number of bound host properties (interpolations illegal)
|
||||
const hostVarsCount = Object.keys(hostBindingsMetadata.properties).length;
|
||||
const elVarExp = o.variable('elIndex');
|
||||
@ -651,14 +651,7 @@ function createHostBindingsFunction(
|
||||
// to the host element alongside any of the provided host attributes that were
|
||||
// collected earlier.
|
||||
const hostAttrs = convertAttributesToExpressions(hostBindingsMetadata.attributes);
|
||||
const hostInstruction = styleBuilder.buildHostAttrsInstruction(null, hostAttrs, constantPool);
|
||||
if (hostInstruction && hostInstruction.calls.length > 0) {
|
||||
createStatements.push(
|
||||
chainedInstruction(
|
||||
hostInstruction.reference,
|
||||
hostInstruction.calls.map(call => convertStylingCall(call, bindingContext, bindingFn)))
|
||||
.toStmt());
|
||||
}
|
||||
styleBuilder.assignHostAttrs(hostAttrs, definitionMap);
|
||||
|
||||
if (styleBuilder.hasBindings) {
|
||||
// finally each binding that was registered in the statement above will need to be added to
|
||||
@ -681,8 +674,7 @@ function createHostBindingsFunction(
|
||||
}
|
||||
|
||||
if (totalHostVarsCount) {
|
||||
createStatements.unshift(
|
||||
o.importExpr(R3.allocHostVars).callFn([o.literal(totalHostVarsCount)]).toStmt());
|
||||
definitionMap.set('hostVars', o.literal(totalHostVarsCount));
|
||||
}
|
||||
|
||||
if (createStatements.length > 0 || updateStatements.length > 0) {
|
||||
|
Reference in New Issue
Block a user