Angular2,从组件内的字符串评估模板
Angular2, evaluate template from string inside a component
是否可以根据变量中的字符串计算模板?。我需要将字符串而不是表达式放在组件中,
例如
template: "<div>{{ template_string }}</div>"
template_string 包含:<b>{{ name }}</b>
并且所有的都应该被评估为 <div><b>My Name</b></div>
但我看到了<div>{{ template_string }}</div>
我需要 {{ template_string | eval }}
之类的东西或其他东西来评估当前上下文中变量的内容。
可能吗?我需要一些东西来使用这种方法,因为 template_string
可以在使用组件时更改。
Edit1:
Angular版本:4.0.3
例如
@Component({
selector: 'product-item',
template: `
<div class="product">{{ template }}</div>`,
})
export class ProductItemComponent {
@Input() name: string;
@Input() price: number = 0;
@Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}
用法:
<product-item [name]="product.name" [price]="product.price"></product-item>
预期:产品名称USD3.00
输出: {{ name }} <b>{{ price | currency }}</b>
不确定您是如何构建模板字符串的
import { ..., OnInit } from '@angular/core';
@Component({
selector: 'product-item',
template: `
<div class="product" [innerHtml]='template_string'>
</div>`,
})
export class ProductItemComponent implements OnInit {
@Input() name: string;
@Input() price: number = 0;
@Input() pre: string;
@Input() mid: string;
@Input() post: string;
template_string;
ngOnInit() {
// this is probably what you want
this.template_string = `${this.pre}${this.name}${this.mid}${this.price}${this.post}`
}
}
<product-item [name]="name" [price]="price" pre="<em>" mid="</em><b>" post="</b>"></product-item>
字符串可以从组件外部构建,但仍然会推荐类似 ngIf 的东西来控制动态模板。
在Angular中,双花括号{{}}
用于评估组件模板中的表达式。并且不适用于随机字符串或动态添加的 DOM 元素。所以这样做的一种方法是使用 ${}
使用打字稿字符串插值。检查其余代码以了解
@Component({
selector: 'product-item',
template: `
<div class="product" [innerHTML]="template"></div>`,
})
export class ProductItemComponent {
@Input() name: string;
@Input() price: number = 0;
@Input() template: string = `${ this.name } <b>${ this.price }}</b>`;
}
您可以创建自己的指令来执行此操作:
compile.directive.ts
@Directive({
selector: '[compile]'
})
export class CompileDirective implements OnChanges {
@Input() compile: string;
@Input() compileContext: any;
compRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
ngOnChanges() {
if(!this.compile) {
if(this.compRef) {
this.updateProperties();
return;
}
throw Error('You forgot to provide template');
}
this.vcRef.clear();
this.compRef = null;
const component = this.createDynamicComponent(this.compile);
const module = this.createDynamicModule(component);
this.compiler.compileModuleAndAllComponentsAsync(module)
.then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
let compFactory = moduleWithFactories.componentFactories.find(x => x.componentType === component);
this.compRef = this.vcRef.createComponent(compFactory);
this.updateProperties();
})
.catch(error => {
console.log(error);
});
}
updateProperties() {
for(var prop in this.compileContext) {
this.compRef.instance[prop] = this.compileContext[prop];
}
}
private createDynamicComponent (template:string) {
@Component({
selector: 'custom-dynamic-component',
template: template,
})
class CustomDynamicComponent {}
return CustomDynamicComponent;
}
private createDynamicModule (component: Type<any>) {
@NgModule({
// You might need other modules, providers, etc...
// Note that whatever components you want to be able
// to render dynamically must be known to this module
imports: [CommonModule],
declarations: [component]
})
class DynamicModule {}
return DynamicModule;
}
}
用法:
@Component({
selector: 'product-item',
template: `
<div class="product">
<ng-container *compile="template; context: this"></ng-container>
</div>
`,
})
export class ProductItemComponent {
@Input() name: string;
@Input() price: number = 0;
@Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}
另见
是否可以根据变量中的字符串计算模板?。我需要将字符串而不是表达式放在组件中, 例如
template: "<div>{{ template_string }}</div>"
template_string 包含:<b>{{ name }}</b>
并且所有的都应该被评估为 <div><b>My Name</b></div>
但我看到了<div>{{ template_string }}</div>
我需要 {{ template_string | eval }}
之类的东西或其他东西来评估当前上下文中变量的内容。
可能吗?我需要一些东西来使用这种方法,因为 template_string
可以在使用组件时更改。
Edit1:
Angular版本:4.0.3
例如
@Component({
selector: 'product-item',
template: `
<div class="product">{{ template }}</div>`,
})
export class ProductItemComponent {
@Input() name: string;
@Input() price: number = 0;
@Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}
用法:
<product-item [name]="product.name" [price]="product.price"></product-item>
预期:产品名称USD3.00
输出: {{ name }} <b>{{ price | currency }}</b>
不确定您是如何构建模板字符串的
import { ..., OnInit } from '@angular/core';
@Component({
selector: 'product-item',
template: `
<div class="product" [innerHtml]='template_string'>
</div>`,
})
export class ProductItemComponent implements OnInit {
@Input() name: string;
@Input() price: number = 0;
@Input() pre: string;
@Input() mid: string;
@Input() post: string;
template_string;
ngOnInit() {
// this is probably what you want
this.template_string = `${this.pre}${this.name}${this.mid}${this.price}${this.post}`
}
}
<product-item [name]="name" [price]="price" pre="<em>" mid="</em><b>" post="</b>"></product-item>
字符串可以从组件外部构建,但仍然会推荐类似 ngIf 的东西来控制动态模板。
在Angular中,双花括号{{}}
用于评估组件模板中的表达式。并且不适用于随机字符串或动态添加的 DOM 元素。所以这样做的一种方法是使用 ${}
使用打字稿字符串插值。检查其余代码以了解
@Component({
selector: 'product-item',
template: `
<div class="product" [innerHTML]="template"></div>`,
})
export class ProductItemComponent {
@Input() name: string;
@Input() price: number = 0;
@Input() template: string = `${ this.name } <b>${ this.price }}</b>`;
}
您可以创建自己的指令来执行此操作:
compile.directive.ts
@Directive({
selector: '[compile]'
})
export class CompileDirective implements OnChanges {
@Input() compile: string;
@Input() compileContext: any;
compRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
ngOnChanges() {
if(!this.compile) {
if(this.compRef) {
this.updateProperties();
return;
}
throw Error('You forgot to provide template');
}
this.vcRef.clear();
this.compRef = null;
const component = this.createDynamicComponent(this.compile);
const module = this.createDynamicModule(component);
this.compiler.compileModuleAndAllComponentsAsync(module)
.then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
let compFactory = moduleWithFactories.componentFactories.find(x => x.componentType === component);
this.compRef = this.vcRef.createComponent(compFactory);
this.updateProperties();
})
.catch(error => {
console.log(error);
});
}
updateProperties() {
for(var prop in this.compileContext) {
this.compRef.instance[prop] = this.compileContext[prop];
}
}
private createDynamicComponent (template:string) {
@Component({
selector: 'custom-dynamic-component',
template: template,
})
class CustomDynamicComponent {}
return CustomDynamicComponent;
}
private createDynamicModule (component: Type<any>) {
@NgModule({
// You might need other modules, providers, etc...
// Note that whatever components you want to be able
// to render dynamically must be known to this module
imports: [CommonModule],
declarations: [component]
})
class DynamicModule {}
return DynamicModule;
}
}
用法:
@Component({
selector: 'product-item',
template: `
<div class="product">
<ng-container *compile="template; context: this"></ng-container>
</div>
`,
})
export class ProductItemComponent {
@Input() name: string;
@Input() price: number = 0;
@Input() template: string = `{{ name }} <b>{{ price | currency }}</b>`;
}
另见