Skip to content

Commit ca81661

Browse files
committed
fix(core): fix property_create instruction breaking binding to Zone targets
The property create instruction is currently failing to bind to Zone targets if there is no advance call before the virtual instruction that selects the intended element.
1 parent 5bf5cac commit ca81661

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

packages/core/src/render3/instructions/property_create.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {isComponentHost} from '../interfaces/type_checks';
2121
import {HEADER_OFFSET, RENDERER} from '../interfaces/view';
2222
import {computed} from '../reactivity/computed';
2323
import {InputSignalNode} from '../reactivity/input_signal';
24-
import {getCurrentTNode, getLView, getSelectedTNode, getTView, nextBindingIndex} from '../state';
24+
import {getCurrentTNode, getLView, getTView, nextBindingIndex} from '../state';
2525
import {renderStringify} from '../util/stringify_utils';
2626
import {getNativeByTNode} from '../util/view_utils';
2727

@@ -96,7 +96,7 @@ export function ɵɵpropertyCreate<T>(
9696
// Some binding targets were zone-based, so we need an update instruction to process them.
9797
(tView.virtualUpdate ??= []).push({
9898
slot: expressionSlot,
99-
instruction: () => propertyUpdateInput(propName, expressionSlot, zoneTargets!),
99+
instruction: () => propertyUpdateInput(tNode.index, propName, expressionSlot, zoneTargets!),
100100
});
101101
} else {
102102
// The only target(s) were signal-based, so no update path is needed.
@@ -138,13 +138,14 @@ export function propertyUpdateDom(
138138
}
139139

140140
export function propertyUpdateInput(
141-
propName: string, expressionSlot: number, targets: PropertyAliasValue): void {
141+
nodeIndex: number, propName: string, expressionSlot: number,
142+
targets: PropertyAliasValue): void {
142143
const lView = getLView();
143144
const expr = lView[expressionSlot];
144145
const value = expr();
145146

146-
const tNode = getSelectedTNode();
147147
const tView = getTView();
148+
const tNode = tView.data[nodeIndex] as TNode;
148149

149150
ngDevMode && assertDefined(tNode.inputs, `Expected tNode to have inputs`);
150151

packages/core/test/acceptance/signal-components/input_bindings.spec.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,33 @@ describe('Signal component inputs', () => {
322322
});
323323

324324
describe('to zone-based targets', () => {
325-
it('works', () => {});
325+
it('should work if there are preceding elements and no `advance` call', () => {
326+
@Directive({
327+
selector: '[dirZone]',
328+
standalone: true,
329+
signals: false,
330+
})
331+
class DirZone {
332+
@Input() works = false;
333+
}
334+
335+
@Component({
336+
signals: true,
337+
template: `
338+
<div></div>
339+
<div dirZone [works]="true"></div>`,
340+
imports: [DirZone],
341+
standalone: true,
342+
})
343+
class App {
344+
}
345+
346+
const fixture = TestBed.createComponent(App);
347+
fixture.detectChanges();
348+
349+
const dirZoneInstance = fixture.debugElement.children[1].injector.get(DirZone);
350+
expect(dirZoneInstance.works).toBe(true);
351+
});
326352
});
327353

328354
describe('to a mix of zone-based and signal-based targets', () => {

0 commit comments

Comments
 (0)