Angular,如何从字符串解析模板并传递当前上下文变量。

21 浏览
0 Comments

Angular,如何从字符串解析模板并传递当前上下文变量。

我正在创建一个简单的组件来创建表格:

@Component({
  selector: 'admin-table',
  template: `
    
{{ column.label }}
`, }) export class AdminTableComponent { @Input() columns: AdminTableColumn[]; @Input() records: {}[]; fieldContent(column: AdminTableColumn, record: {}) { if (column.template) { //TODO: 解析模板并将当前记录作为参数传递 return column.template; } return record[column.field]; } }

还有另一个组件,使用上述组件创建产品表格

@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 })的东西。

0
0 Comments

问题的出现原因是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 }}
`, }) export class AdminTableComponent { columns: AdminTableColumn[]; records: {}[]; fieldContent(column: AdminTableColumn, record: {}) { if (column.template) { let template = column.template; // Go through the keys and replace all instances in the field. // Note that this is strict and will not replace {{ record.name }} // You may want to add additional regexp to do that. Object.keys(record).forEach(key => { template = template.replace(new RegExp(`{{record.${key}}}`, 'g'), 'some name'); }); return template; } return record[column.field]; } }

感谢您的回答,但是这种方法已经被丢弃了,因为在模板中无法使用管道或其他组件。我更希望能够渲染我所需的内容。

0
0 Comments

在这段代码中,问题是如何从字符串中解析模板并传递当前上下文变量。解决方法是创建一个特殊的指令来实现这个目的。指令名为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中的静态模板来显示记录的字段值。

通过上述方法,我们可以从字符串中解析模板并传递当前上下文变量,实现动态渲染组件和模板的功能。

0