8000 fix(compiler-cli): only bind inputs that are part of microsyntax to a structural directive by JoostK · Pull Request #52453 · angular/angular · GitHub
[go: up one dir, main page]

Skip to content

fix(compiler-cli): only bind inputs that are part of microsyntax to a structural directive #52453

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fix(compiler-cli): only bind inputs that are part of microsyntax to a…
… structural directive

Prior to this change the template type-check generator would incorrectly apply inputs
and attributes to a structural directive, where only the bindings as present in microsyntax
are actually bound to the directive. This introduced a problem where usages of template
variables could not be resolved, because the template variables are out-of-scope of the
template element itself.

Closes #49931
  • Loading branch information
JoostK committed Oct 6, 2024
commit ba9865ba0b3a24c5051fc0c5935f6714bfd4194c
Original file line number Diff line number Diff line change
Expand Up @@ -2971,10 +2971,16 @@ function getBoundAttributes(
}
};

node.inputs.forEach(processAttribute);
node.attributes.forEach(processAttribute);
if (node instanceof TmplAstTemplate) {
if (node.tagName === 'ng-template') {
node.inputs.forEach(processAttribute);
node.attributes.forEach(processAttribute);
}

node.templateAttrs.forEach(processAttribute);
} else {
node.inputs.forEach(processAttribute);
node.attributes.forEach(processAttribute);
}

return boundInputs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,50 @@ describe('type check blocks', () => {
expect(block).not.toContain('NoReference');
});

it('should not bind inputs outside of microsyntax to a structural directive', () => {
const TEMPLATE = `
<my-dir *ngFor="let foo of foos" [ngForTrackBy]="foo"></my-dir>
`;
const DIRECTIVES: TestDeclaration[] = [
{
type: 'directive',
name: 'NgFor',
selector: '[ngFor][ngForOf]',
inputs: {ngForOf: 'ngForOf', ngForTrackBy: 'ngForTrackBy'},
},
{
type: 'directive',
name: 'MyDir',
selector: 'my-dir',
inputs: {ngForTrackBy: 'ngForTrackBy'},
},
];
const block = tcb(TEMPLATE, DIRECTIVES);
expect(block).toContain('var _t1 = null! as i0.NgFor');
expect(block).toContain('_t1.ngForOf = (((this).foos))');
expect(block).not.toContain('_t1.ngForTrackBy');
expect(block).toContain('var _t4 = null! as i0.MyDir');
expect(block).toContain('_t4.ngForTrackBy =');
});

it('should bind inputs to a structural directive when used on ng-template', () => {
const TEMPLATE = `
<ng-template ngFor [ngForOf]="foos" let-foo [ngForTrackBy]="foo"></ng-template>
`;
const DIRECTIVES: TestDeclaration[] = [
{
type: 'directive',
name: 'NgFor',
selector: '[ngFor][ngForOf]',
inputs: {ngForOf: 'ngForOf', ngForTrackBy: 'ngForTrackBy'},
},
];
const block = tcb(TEMPLATE, DIRECTIVES);
expect(block).toContain('var _t1 = null! as i0.NgFor');
expect(block).toContain('_t1.ngForOf = (((this).foos))');
expect(block).toContain('_t1.ngForTrackBy = (((this).foo))');
});

it('should generate a forward element reference correctly', () => {
const TEMPLATE = `
{{ i.value }}
Expand Down
0