Angular 2中如何在创建表格行时调用方法?
问题分析与解决建议
哥们,你遇到的核心问题是Angular的*ngFor指令并没有onCreate这类输出事件,你在<tr>上绑定的(onCreate)是自定义的、Angular不识别的事件,所以你的formatXml方法根本不会被触发。另外你的formatXml方法里还有个小bug:开头的xml = '';直接把传入的参数清空了,就算方法被调用也得不到正确结果。
下面给你两种靠谱的解决方案,按需选择:
方案一:使用Angular管道(推荐,适合纯数据转换场景)
格式化XML属于纯数据转换操作,用Angular管道是最符合最佳实践的方式,它会自动帮你在数据变化时重新格式化,而且模板代码更简洁。
步骤1:创建格式化XML的管道
在你的项目里新建一个管道文件(比如format-xml.pipe.ts),把格式化逻辑搬进去:
import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'formatXml' }) export class FormatXmlPipe implements PipeTransform { transform(xml: string): string { // 先处理空值,避免报错 let formattedXml = xml || ''; // 替换标签换行 const reg = /(>)(<)(\/*)/g; formattedXml = formattedXml.replace(reg, '$1\r\n$2$3'); let pad = 0; const lines = formattedXml.split('\r\n'); formattedXml = ''; lines.forEach(node => { let indent = 0; if (node.match(/.+<\/\w[^>]*>$/)) { indent = 0; } else if (node.match(/^<\/\w/)) { if (pad !== 0) { pad -= 1; } } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) { indent = 1; } else { indent = 0; } const padding = ' '.repeat(pad); formattedXml += padding + node + '\r\n'; pad += indent; }); return formattedXml; } }
步骤2:在模块中声明管道
打开你的组件所在的模块(比如app.module.ts),把管道添加到declarations数组里:
import { FormatXmlPipe } from './format-xml.pipe'; @NgModule({ declarations: [ // ...其他组件/指令 FormatXmlPipe ], // ...其他配置 }) export class AppModule { }
步骤3:在模板中使用管道
直接在*ngFor循环里用管道格式化car.ID:
<div class="table-responsive"> <table class="table table-bordred table-striped "> <tbody> <tr *ngFor="let car of cars; let i = index;"> <td>{{ car.ID | formatXml }}</td> </tr> </tbody> </table> </div>
方案二:提前在组件中处理数据
如果你的XML数据不会频繁变化,也可以在组件里提前把所有car的格式化XML处理好,然后直接在模板里渲染:
步骤1:修改组件逻辑
在你获取cars数据的地方(比如ngOnInit或者数据订阅的回调里),给每个car添加一个格式化后的属性:
// 假设你是这样获取cars的 ngOnInit() { // 模拟获取数据 this.cars = [/* 你的car数据 */]; // 提前格式化每个car的XML this.cars.forEach(car => { car.formattedXml = this.formatXml(car.ID); }); } // 修正后的formatXml方法 formatXml(xml: string): string { let formattedXml = xml || ''; const reg = /(>)(<)(\/*)/g; formattedXml = formattedXml.replace(reg, '$1\r\n$2$3'); let pad = 0; const lines = formattedXml.split('\r\n'); formattedXml = ''; lines.forEach(node => { let indent = 0; if (node.match(/.+<\/\w[^>]*>$/)) { indent = 0; } else if (node.match(/^<\/\w/)) { if (pad !== 0) { pad -= 1; } } else if (node.match(/^<\w[^>]*[^\/]>.*$/)) { indent = 1; } else { indent = 0; } const padding = ' '.repeat(pad); formattedXml += padding + node + '\r\n'; pad += indent; }); return formattedXml; }
步骤2:在模板中直接渲染处理好的数据
<div class="table-responsive"> <table class="table table-bordred table-striped "> <tbody> <tr *ngFor="let car of cars; let i = index;"> <td>{{ car.formattedXml }}</td> </tr> </tbody> </table> </div>
额外注意点
- 原方法里的
xml = '';一定要删掉,改成let formattedXml = xml || '';,不然传入的XML会被清空,格式化结果永远是空的。 - 如果你的
car.ID本身不是XML字符串,还要先确认数据格式是否正确,避免格式化逻辑报错。
内容的提问来源于stack exchange,提问作者bellotas
相关产品推荐
相关产品推荐

