fix(ivy): generate bind calls for property bindings (#23403)
PR Close #23403
This commit is contained in:

committed by
Jason Aden

parent
010a4efa8c
commit
7f612fc828
@ -722,7 +722,7 @@ class TemplateDefinitionBuilder implements TemplateAstVisitor, LocalResolver {
|
|||||||
// TODO(chuckj): runtime: security context?
|
// TODO(chuckj): runtime: security context?
|
||||||
this.instruction(
|
this.instruction(
|
||||||
this._bindingMode, input.sourceSpan, instruction, o.literal(elementIndex),
|
this._bindingMode, input.sourceSpan, instruction, o.literal(elementIndex),
|
||||||
o.literal(input.name), convertedBinding);
|
o.literal(input.name), o.importExpr(R3.bind).callFn([convertedBinding]));
|
||||||
} else {
|
} else {
|
||||||
this.unsupported(`binding ${PropertyBindingType[input.type]}`);
|
this.unsupported(`binding ${PropertyBindingType[input.type]}`);
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,91 @@ describe('compiler compliance', () => {
|
|||||||
expectEmit(result.source, factory, 'Incorrect factory');
|
expectEmit(result.source, factory, 'Incorrect factory');
|
||||||
expectEmit(result.source, template, 'Incorrect template');
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should bind to element properties', () => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`<div [id]="id"></div>\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
id = 'one';
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
|
||||||
|
const template = `
|
||||||
|
…
|
||||||
|
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
||||||
|
if (rf & 1) {
|
||||||
|
$r3$.ɵE(0, 'div');
|
||||||
|
$r3$.ɵe();
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
$r3$.ɵp(0, 'id', $r3$.ɵb(ctx.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
|
||||||
|
expectEmit(result.source, factory, 'Incorrect factory');
|
||||||
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should bind to class and style names', () => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`<div [class.error]="error" [style.background-color]="color"></div>\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
error = true;
|
||||||
|
color = 'red';
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
|
||||||
|
const template = `
|
||||||
|
…
|
||||||
|
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) {
|
||||||
|
if (rf & 1) {
|
||||||
|
$r3$.ɵE(0, 'div');
|
||||||
|
$r3$.ɵe();
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
$r3$.ɵkn(0, 'error', $r3$.ɵb(ctx.error));
|
||||||
|
$r3$.ɵsn(0, 'background-color', $r3$.ɵb(ctx.color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
|
||||||
|
expectEmit(result.source, factory, 'Incorrect factory');
|
||||||
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('components & directives', () => {
|
describe('components & directives', () => {
|
||||||
|
@ -16,7 +16,7 @@ describe('compiler compliance: template', () => {
|
|||||||
compileCommon: true,
|
compileCommon: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create correctly bind to context in nested template', () => {
|
it('should correctly bind to context in nested template', () => {
|
||||||
const files = {
|
const files = {
|
||||||
app: {
|
app: {
|
||||||
'spec.ts': `
|
'spec.ts': `
|
||||||
@ -94,7 +94,7 @@ describe('compiler compliance: template', () => {
|
|||||||
const $outer$ = ctx0.$implicit;
|
const $outer$ = ctx0.$implicit;
|
||||||
const $middle$ = ctx1.$implicit;
|
const $middle$ = ctx1.$implicit;
|
||||||
const $inner$ = ctx2.$implicit;
|
const $inner$ = ctx2.$implicit;
|
||||||
$i0$.ɵp(0, 'title', ctx.format($outer$, $middle$, $inner$, ctx.component));
|
$i0$.ɵp(0, 'title', $i0$.ɵb(ctx.format($outer$, $middle$, $inner$, ctx.component)));
|
||||||
$i0$.ɵt(1, $i0$.ɵi1(' ', ctx.format($outer$, $middle$, $inner$, ctx.component), ' '));
|
$i0$.ɵt(1, $i0$.ɵi1(' ', ctx.format($outer$, $middle$, $inner$, ctx.component), ' '));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user