fix(ivy): ensure styling pipes are allocated before used in bindings (#26593)
PR Close #26593
This commit is contained in:
parent
67789f10ef
commit
f6c2db818e
@ -625,5 +625,46 @@ describe('compiler compliance: styling', () => {
|
|||||||
expectEmit(result.source, template, 'Incorrect template');
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should stamp out pipe definitions in the creation block if used by styling bindings',
|
||||||
|
() => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, NgModule} from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`<div [style]="myStyleExp | stylePipe" [class]="myClassExp | classPipe"></div>\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
myStyleExp = [{color:'red'}, {color:'blue', duration:1000}]
|
||||||
|
myClassExp = 'foo bar apple';
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const template = `
|
||||||
|
template: function MyComponent_Template(rf, $ctx$) {
|
||||||
|
if (rf & 1) {
|
||||||
|
$r3$.ɵelementStart(0, "div");
|
||||||
|
$r3$.ɵelementStyling(null, null, $r3$.ɵdefaultStyleSanitizer);
|
||||||
|
$r3$.ɵpipe(1, "classPipe");
|
||||||
|
$r3$.ɵpipe(2, "stylePipe");
|
||||||
|
$r3$.ɵelementEnd();
|
||||||
|
}
|
||||||
|
if (rf & 2) {
|
||||||
|
$r3$.ɵelementStylingMap(0, $r3$.ɵpipeBind1(1, 0, $ctx$.myClassExp), $r3$.ɵpipeBind1(2, 2, $ctx$.myStyleExp));
|
||||||
|
$r3$.ɵelementStylingApply(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
expectEmit(result.source, template, 'Incorrect template');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -643,18 +643,23 @@ export class TemplateDefinitionBuilder implements t.Visitor<void>, LocalResolver
|
|||||||
|
|
||||||
const stylingInput = mapBasedStyleInput || mapBasedClassInput;
|
const stylingInput = mapBasedStyleInput || mapBasedClassInput;
|
||||||
if (stylingInput) {
|
if (stylingInput) {
|
||||||
|
// these values must be outside of the update block so that they can
|
||||||
|
// be evaluted (the AST visit call) during creation time so that any
|
||||||
|
// pipes can be picked up in time before the template is built
|
||||||
|
const mapBasedClassValue =
|
||||||
|
mapBasedClassInput ? mapBasedClassInput.value.visit(this._valueConverter) : null;
|
||||||
|
const mapBasedStyleValue =
|
||||||
|
mapBasedStyleInput ? mapBasedStyleInput.value.visit(this._valueConverter) : null;
|
||||||
this.updateInstruction(stylingInput.sourceSpan, R3.elementStylingMap, () => {
|
this.updateInstruction(stylingInput.sourceSpan, R3.elementStylingMap, () => {
|
||||||
const params: o.Expression[] = [indexLiteral];
|
const params: o.Expression[] = [indexLiteral];
|
||||||
|
|
||||||
if (mapBasedClassInput) {
|
if (mapBasedClassValue) {
|
||||||
const mapBasedClassValue = mapBasedClassInput.value.visit(this._valueConverter);
|
|
||||||
params.push(this.convertPropertyBinding(implicit, mapBasedClassValue, true));
|
params.push(this.convertPropertyBinding(implicit, mapBasedClassValue, true));
|
||||||
} else if (mapBasedStyleInput) {
|
} else if (mapBasedStyleInput) {
|
||||||
params.push(o.NULL_EXPR);
|
params.push(o.NULL_EXPR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapBasedStyleInput) {
|
if (mapBasedStyleValue) {
|
||||||
const mapBasedStyleValue = mapBasedStyleInput.value.visit(this._valueConverter);
|
|
||||||
params.push(this.convertPropertyBinding(implicit, mapBasedStyleValue, true));
|
params.push(this.convertPropertyBinding(implicit, mapBasedStyleValue, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user