Angular,如何从字符串解析模板并传递当前上下文变量。
Angular,如何从字符串解析模板并传递当前上下文变量。
我正在创建一个简单的组件来创建表格:
@Component({ selector: 'admin-table', template: `
{{ column.label }} |
---|
还有另一个组件,使用上述组件创建产品表格
@Component({ selector: 'product-admin', template: `产品
`, providers: [ProductService], }) export class ProductAdminComponent implements OnInit { products: Product[]; columns: AdminTableColumn[] = [ { field: 'id', label: 'SKU', }, { field: 'name', label: '名称', template: '{{record.name}}', } ]; }
如您所见,AdminTableColumn
有一个额外的选项叫做template
来使用模板设置单元格的值。但是,当我尝试渲染该值时,我得到的是{{record.name}}
而不是实际的产品名称。
我需要解析在template
选项中输入的值,以便使用angular声明,比如:{{record.name}}
或
,以创建一个丰富的表格。
换句话说,存在类似render(template, { record: record })
的东西。
问题的出现原因是Angular在通过innerHtml注入HTML时会对HTML进行清理,因此无法使用字符串插值。为了解决这个问题,我们可以尝试在fieldContent函数中解析模板,并直接添加记录的键。
解决方法如下所示:
1. 首先,我们定义一个正则表达式,用于替换模板中的{{record[key]}},不论key是什么,并将插值后的字符串返回以注入到HTML中。
2. 在fieldContent函数中,如果存在column.template,则将模板赋值给一个变量template。
3. 遍历record的所有键,并使用正则表达式替换模板中的所有实例。需要注意的是,这个替换是严格匹配的,不会替换{{record.name}}这样的表达式。如果需要替换这样的表达式,可以添加额外的正则表达式来实现。
4. 如果column.template不存在,直接返回record[column.field]。
下面是一个示例代码,演示了如何使用这种解决方法:
({ selector: 'admin-table', template: `
{{ column.label }} |
---|
感谢您的回答,但是这种方法已经被丢弃了,因为在模板中无法使用管道或其他组件。我更希望能够渲染我所需的内容。
在这段代码中,问题是如何从字符串中解析模板并传递当前上下文变量。解决方法是创建一个特殊的指令来实现这个目的。指令名为CompileDirective,实现了OnChanges接口。它包含了一个compile属性和一个compileContext属性,用于接收模板字符串和当前上下文变量。在ngOnChanges方法中,首先检查compile属性是否为空,如果为空则抛出错误。然后清空视图容器,并将compRef设置为null。接下来,使用createDynamicComponent方法创建一个动态组件,并使用createDynamicModule方法创建一个动态模块。然后,使用compiler.compileModuleAndAllComponentsAsync方法编译模块和组件,并获取组件工厂。最后,使用vcRef.createComponent方法创建组件实例,并调用updateProperties方法更新组件属性。updateProperties方法遍历compileContext中的属性,并将其赋值给组件实例的对应属性。
在AdminComponent中,使用了AdminTableComponent组件来展示一个表格。表格的每一列都有一个模板,可以根据需要动态渲染。通过ng-container和ng-template来实现动态渲染。在ng-container中,使用compile指令来解析模板字符串,并传递record变量作为上下文。如果模板字符串不存在,使用ng-template中的静态模板来显示记录的字段值。
通过上述方法,我们可以从字符串中解析模板并传递当前上下文变量,实现动态渲染组件和模板的功能。