fix(ivy): ngtsc should correctly bind to context in nested template with many bindings (#28982)
PR Close #28982
This commit is contained in:
parent
25a2fef303
commit
8f8f9a6e61
|
@ -117,6 +117,63 @@ describe('compiler compliance: template', () => {
|
||||||
expectEmit(result.source, template, 'Incorrect template');
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should correctly bind to context in nested template with many bindings', () => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`
|
||||||
|
<div *ngFor="let d of _data; let i = index" (click)="_handleClick(d, i)"></div>
|
||||||
|
\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
_data = [1,2,3];
|
||||||
|
_handleClick(d: any, i: any) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const template = `
|
||||||
|
const $t0_attrs$ = ["ngFor", "", ${AttributeMarker.SelectOnly}, "ngForOf"];
|
||||||
|
const $e_attrs$ = [${AttributeMarker.SelectOnly}, "click"];
|
||||||
|
|
||||||
|
function MyComponent_div_0_Template(rf, ctx) {
|
||||||
|
if (rf & 1) {
|
||||||
|
const $s$ = $r3$.ɵgetCurrentView();
|
||||||
|
$r3$.ɵelementStart(0, "div", $e_attrs$);
|
||||||
|
$r3$.ɵlistener("click", function MyComponent_div_0_Template_div_click_0_listener($event) {
|
||||||
|
$r3$.ɵrestoreView($s$);
|
||||||
|
const $d$ = ctx.$implicit;
|
||||||
|
const $i$ = ctx.index;
|
||||||
|
const $comp$ = $r3$.ɵnextContext();
|
||||||
|
return $comp$._handleClick($d$, $i$);
|
||||||
|
});
|
||||||
|
$r3$.ɵelementEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ...
|
||||||
|
template: function MyComponent_Template(rf, ctx) {
|
||||||
|
if (rf & 1) {
|
||||||
|
$r3$.ɵtemplate(0, MyComponent_div_0_Template, 1, 0, "div", $t0_attrs$);
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
$r3$.ɵelementProperty(0, "ngForOf", $r3$.ɵbind(ctx._data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
|
||||||
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
|
});
|
||||||
|
|
||||||
it('should support ngFor context variables', () => {
|
it('should support ngFor context variables', () => {
|
||||||
const files = {
|
const files = {
|
||||||
app: {
|
app: {
|
||||||
|
|
|
@ -1431,7 +1431,8 @@ export class BindingScope implements LocalResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeGenerateSharedContextVar(value: BindingData) {
|
maybeGenerateSharedContextVar(value: BindingData) {
|
||||||
if (value.priority === DeclarationPriority.CONTEXT) {
|
if (value.priority === DeclarationPriority.CONTEXT &&
|
||||||
|
value.retrievalLevel < this.bindingLevel) {
|
||||||
const sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + value.retrievalLevel);
|
const sharedCtxObj = this.map.get(SHARED_CONTEXT_KEY + value.retrievalLevel);
|
||||||
if (sharedCtxObj) {
|
if (sharedCtxObj) {
|
||||||
sharedCtxObj.declare = true;
|
sharedCtxObj.declare = true;
|
||||||
|
|
|
@ -597,30 +597,6 @@ window.testBlocklist = {
|
||||||
"error": "TypeError: Cannot read property 'getBoundingClientRect' of null",
|
"error": "TypeError: Cannot read property 'getBoundingClientRect' of null",
|
||||||
"notes": "Unknown"
|
"notes": "Unknown"
|
||||||
},
|
},
|
||||||
"MatTabGroup basic behavior should change selected index on click": {
|
|
||||||
"error": "Error: Expected 0 to be 1.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatTabGroup basic behavior should support two-way binding for selectedIndex": {
|
|
||||||
"error": "TypeError: ctx_r16151._handleClick is not a function",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatTabGroup basic behavior should fire animation done event": {
|
|
||||||
"error": "TypeError: ctx_r16547._handleClick is not a function",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatTabGroup basic behavior should emit focusChange event on click": {
|
|
||||||
"error": "Error: Expected spy handleFocus to have been called once. It was called 0 times.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatTabGroup basic behavior should emit focusChange on arrow key navigation": {
|
|
||||||
"error": "Error: Expected spy handleFocus to have been called once. It was called 0 times.",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"MatTabGroup lazy loaded tabs should lazy load the second tab": {
|
|
||||||
"error": "TypeError: ctx_r17471._handleClick is not a function",
|
|
||||||
"notes": "Unknown"
|
|
||||||
},
|
|
||||||
"Dialog should set the proper animation states": {
|
"Dialog should set the proper animation states": {
|
||||||
"error": "TypeError: Cannot read property 'componentInstance' of null",
|
"error": "TypeError: Cannot read property 'componentInstance' of null",
|
||||||
"notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
|
"notes": "FW-1059: DebugNode.query should query nodes in the logical tree"
|
||||||
|
|
Loading…
Reference in New Issue