Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 334d851

Browse files
crisbetokirjs
authored andcommitted
refactor(core): add infrastructure for setting inputs on specific directives (#60075)
Sets up the infrastructure that will allow to write only to a specific directive and its host directives as a base for future functionality. I've also renamed `setInputsForProperty` to be a bit more explicit that its sets all inputs. PR Close #60075
1 parent 87a0fb9 commit 334d851

File tree

14 files changed

+95
-17
lines changed

14 files changed

+95
-17
lines changed

‎packages/core/src/render3/component_ref.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {renderView} from './instructions/render';
3838
import {
3939
createDirectivesInstances,
4040
locateHostElement,
41-
setInputsForProperty,
41+
setAllInputsForProperty,
4242
} from './instructions/shared';
4343
import {ComponentDef, DirectiveDef} from './interfaces/definition';
4444
import {InputFlags} from './interfaces/input_flags';
@@ -392,7 +392,7 @@ export class ComponentRef<T> extends AbstractComponentRef<T> {
392392
}
393393

394394
const lView = this._rootLView;
395-
const hasSetInput = setInputsForProperty(tNode, lView[TVIEW], lView, name, value);
395+
const hasSetInput = setAllInputsForProperty(tNode, lView[TVIEW], lView, name, value);
396396
this.previousInputValues.set(name, value);
397397
const childComponentLView = getComponentLViewByIndex(tNode.index, lView);
398398
markViewDirty(childComponentLView, NotificationSource.SetInput);

‎packages/core/src/render3/instructions/property.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {getLView, getSelectedTNode, getTView, nextBindingIndex} from '../state';
1313

1414
import {
1515
elementPropertyInternal,
16-
setInputsForProperty,
16+
setAllInputsForProperty,
1717
storePropertyBindingMetadata,
1818
} from './shared';
1919

@@ -72,5 +72,5 @@ export function setDirectiveInputsWhichShadowsStyling(
7272
isClassBased: boolean,
7373
) {
7474
// We support both 'class' and `className` hence the fallback.
75-
setInputsForProperty(tNode, tView, lView, isClassBased ? 'class' : 'style', value);
75+
setAllInputsForProperty(tNode, tView, lView, isClassBased ? 'class' : 'style', value);
7676
}

‎packages/core/src/render3/instructions/shared.ts‎

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export function elementPropertyInternal<T>(
251251
ngDevMode && assertNotSame(value, NO_CHANGE as any, 'Incoming value should never be NO_CHANGE.');
252252

253253
if (!nativeOnly) {
254-
const hasSetInput = setInputsForProperty(tNode, tView, lView, propName, value);
254+
const hasSetInput = setAllInputsForProperty(tNode, tView, lView, propName, value);
255255

256256
if (hasSetInput) {
257257
isComponentHost(tNode) && markDirtyIfOnPush(lView, tNode.index);
@@ -614,14 +614,15 @@ export function handleError(lView: LView, error: any): void {
614614
}
615615

616616
/**
617-
* Set the inputs of directives at the current node to corresponding value.
617+
* Set all directive inputs with the specific public name on the node.
618618
*
619619
* @param tNode TNode on which the input is being set.
620-
* @param tView The current TView
621-
* @param lView the `LView` which contains the directives.
620+
* @param tView Current TView
621+
* @param lView `LView` which contains the directives.
622+
* @param publicName Public name of the input being set.
622623
* @param value Value to set.
623624
*/
624-
export function setInputsForProperty(
625+
export function setAllInputsForProperty(
625626
tNode: TNode,
626627
tView: TView,
627628
lView: LView,
@@ -655,3 +656,69 @@ export function setInputsForProperty(
655656

656657
return hasMatch;
657658
}
659+
660+
/**
661+
* Sets an input value only on a specific directive and its host directives.
662+
* @param tNode TNode on which the input is being set.
663+
* @param tView Current TView
664+
* @param lView `LView` which contains the directives.
665+
* @param target Directive on which to set the input.
666+
* @param publicName Public name of the input being set.
667+
* @param value Value to set.
668+
*/
669+
export function setDirectiveInput(
670+
tNode: TNode,
671+
tView: TView,
672+
lView: LView,
673+
target: DirectiveDef<unknown>,
674+
publicName: string,
675+
value: string,
676+
): boolean {
677+
let hostIndex: number | null = null;
678+
let hostDirectivesStart: number | null = null;
679+
let hostDirectivesEnd: number | null = null;
680+
let hasSet = false;
681+
682+
if (ngDevMode && !tNode.directiveToIndex?.has(target.type)) {
683+
throw new Error(`Node does not have a directive with type ${target.type.name}`);
684+
}
685+
686+
const data = tNode.directiveToIndex!.get(target.type)!;
687+
688+
if (typeof data === 'number') {
689+
hostIndex = data;
690+
} else {
691+
[hostIndex, hostDirectivesStart, hostDirectivesEnd] = data;
692+
}
693+
694+
if (
695+
hostDirectivesStart !== null &&
696+
hostDirectivesEnd !== null &&
697+
tNode.hostDirectiveInputs?.hasOwnProperty(publicName)
698+
) {
699+
const hostDirectiveInputs = tNode.hostDirectiveInputs[publicName];
700+
701+
for (let i = 0; i < hostDirectiveInputs.length; i += 2) {
702+
const index = hostDirectiveInputs[i] as number;
703+
704+
if (index >= hostDirectivesStart && index <= hostDirectivesEnd) {
705+
ngDevMode && assertIndexInRange(lView, index);
706+
const def = tView.data[index] as DirectiveDef<unknown>;
707+
const hostDirectivePublicName = hostDirectiveInputs[i + 1] as string;
708+
writeToDirectiveInput(def, lView[index], hostDirectivePublicName, value);
709+
hasSet = true;
710+
} else if (index > hostDirectivesEnd) {
711+
// Directives here are in ascending order so we can stop looking once we're past the range.
712+
break;
713+
}
714+
}
715+
}
716+
717+
if (hostIndex !== null) {
718+
ngDevMode && assertIndexInRange(lView, hostIndex);
719+
writeToDirectiveInput(target, lView[hostIndex], publicName, value);
720+
hasSet = true;
721+
}
722+
723+
return hasSet;
724+
}

‎packages/core/test/bundling/animations-standalone/bundle.golden_symbols.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@
395395
"makeTimingAst",
396396
"map",
397397
"markAncestorsForTraversal",
398+
"markAsComponentHost",
398399
"markViewDirty",
399400
"markViewForRefresh",
400401
"markedFeatures",
@@ -451,6 +452,7 @@
451452
"scheduleCallbackWithRafRace",
452453
"searchTokensOnInjector",
453454
"setActiveConsumer",
455+
"setAllInputsForProperty",
454456
"setBindingRootForHostBindings",
455457
"setCurrentDirectiveIndex",
456458
"setCurrentInjector",
@@ -459,7 +461,6 @@
459461
"setDirectiveInputsWhichShadowsStyling",
460462
"setIncludeViewProviders",
461463
"setInjectImplementation",
462-
"setInputsForProperty",
463464
"setInputsFromAttrs",
464465
"setIsRefreshingViews",
465466
"setSelectedIndex",

‎packages/core/test/bundling/animations/bundle.golden_symbols.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@
418418
"makeTimingAst",
419419
"map",
420420
"markAncestorsForTraversal",
421+
"markAsComponentHost",
421422
"markViewDirty",
422423
"markViewForRefresh",
423424
"markedFeatures",
@@ -477,6 +478,7 @@
477478
"scheduleCallbackWithRafRace",
478479
"searchTokensOnInjector",
479480
"setActiveConsumer",
481+
"setAllInputsForProperty",
480482
"setBindingRootForHostBindings",
481483
"setCurrentDirectiveIndex",
482484
"setCurrentInjector",
@@ -485,7 +487,6 @@
485487
"setDirectiveInputsWhichShadowsStyling",
486488
"setIncludeViewProviders",
487489
"setInjectImplementation",
488-
"setInputsForProperty",
489490
"setInputsFromAttrs",
490491
"setIsRefreshingViews",
491492
"setSelectedIndex",

‎packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@
337337
"makeRecord",
338338
"map",
339339
"markAncestorsForTraversal",
340+
"markAsComponentHost",
340341
"markViewDirty",
341342
"markViewForRefresh",
342343
"markedFeatures",
@@ -385,6 +386,7 @@
385386
"scheduleCallbackWithRafRace",
386387
"searchTokensOnInjector",
387388
"setActiveConsumer",
389+
"setAllInputsForProperty",
388390
"setBindingRootForHostBindings",
389391
"setCurrentDirectiveIndex",
390392
"setCurrentInjector",
@@ -393,7 +395,6 @@
393395
"setDirectiveInputsWhichShadowsStyling",
394396
"setIncludeViewProviders",
395397
"setInjectImplementation",
396-
"setInputsForProperty",
397398
"setInputsFromAttrs",
398399
"setIsRefreshingViews",
399400
"setSelectedIndex",

‎packages/core/test/bundling/defer/bundle.golden_symbols.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,7 @@
796796
"makeRecord",
797797
"map",
798798
"markAncestorsForTraversal",
799+
"markAsComponentHost",
799800
"markViewDirty",
800801
"markViewForRefresh",
801802
"markedFeatures",
@@ -851,6 +852,7 @@
851852
"searchTokensOnInjector",
852853
"selectIndexInternal",
853854
"setActiveConsumer",
855+
"setAllInputsForProperty",
854856
"setBindingRootForHostBindings",
855857
"setCurrentDirectiveIndex",
856858
"setCurrentInjector",
@@ -859,7 +861,6 @@
859861
"setDirectiveInputsWhichShadowsStyling",
860862
"setIncludeViewProviders",
861863
"setInjectImplementation",
862-
"setInputsForProperty",
863864
"setInputsFromAttrs",
864865
"setIsRefreshingViews",
865866
"setSelectedIndex",

‎packages/core/test/bundling/forms_reactive/bundle.golden_symbols.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@
501501
"makeValidatorsArray",
502502
"map",
503503
"markAncestorsForTraversal",
504+
"markAsComponentHost",
504505
"markDuplicates",
505506
"markViewDirty",
506507
"markViewForRefresh",
@@ -580,6 +581,7 @@
580581
"searchTokensOnInjector",
581582
"selectIndexInternal",
582583
"setActiveConsumer",
584+
"setAllInputsForProperty",
583585
"setBindingRootForHostBindings",
584586
"setCurrentDirectiveIndex",
585587
"setCurrentInjector",
@@ -589,7 +591,6 @@
589591
"setDisabledStateDefault",
590592
"setIncludeViewProviders",
591593
"setInjectImplementation",
592-
"setInputsForProperty",
593594
"setInputsFromAttrs",
594595
"setIsRefreshingViews",
595596
"setSelectedIndex",

‎packages/core/test/bundling/forms_template_driven/bundle.golden_symbols.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@
488488
"makeValidatorsArray",
489489
"map",
490490
"markAncestorsForTraversal",
491+
"markAsComponentHost",
491492
"markDuplicates",
492493
"markViewDirty",
493494
"markViewForRefresh",
@@ -573,6 +574,7 @@
573574
"searchTokensOnInjector",
574575
"selectIndexInternal",
575576
"setActiveConsumer",
577+
"setAllInputsForProperty",
576578
"setBindingRootForHostBindings",
577579
"setCurrentDirectiveIndex",
578580
"setCurrentInjector",
@@ -582,7 +584,6 @@
582584
"setDisabledStateDefault",
583585
"setIncludeViewProviders",
584586
"setInjectImplementation",
585-
"setInputsForProperty",
586587
"setInputsFromAttrs",
587588
"setIsRefreshingViews",
588589
"setSelectedIndex",

‎packages/core/test/bundling/hello_world/bundle.golden_symbols.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@
270270
"makeRecord",
271271
"map",
272272
"markAncestorsForTraversal",
273+
"markAsComponentHost",
273274
"markViewDirty",
274275
"markViewForRefresh",
275276
"maybeWrapInNotSelector",

0 commit comments

Comments
 (0)