你好 我的名字叫罗马,我不是自行车的发明者。 我喜欢Angular框架及其周围的生态系统,并以此开发我的Web应用程序。 从我的角度来看,从长远来看,Angular的主要优势是基于HTML和TypeScript之间的代码分离,这是由其开发人员
之一详细描述
的。why-angular-renders-components-with.html此优势有一个缺点:原则上需要编译以及在运行时动态编译组件的复杂性。 我想使用熟悉的Angular模板语法为用户的应用程序提供自定义字母模板,生成用于打印的报告和电子表格或为xml文件设置导出格式的能力! 要了解如何做到这一点,欢迎猫!
挑战赛
通常,用户使用Angular模板可能看起来像这样:我们有一定的数据集:
const data = { project: 'MySuperProject', userName: 'Roman', role: 'admin', projectLink: 'https://example.com/my-super-projectproject' }
有必要提供自定义字母文本的机会,该字母文本将在编辑项目后发送给用户。 使用Angular模板,它可能看起来像这样:
<body> ! {{project}} <a href="{{projectLink}}">3D </a> <div *ngIf="role == 'admin'"> <a href="{{projectLink}}?mode=edit"></a> </div> </body>
Ng模板库
使用客户端(甚至服务器端)上的Angular编译器可以解决此问题,但是这非常耗时,并且需要将大量兆字节的代码拖到客户端。 为什么Angular编译器这么大? 这是因为它支持大量用于组成组件和模块的功能,并且还包含自己的HTML解析器! 因此,我决定编写一个最小的Angular模板转换器,该转换器将使用浏览器中内置的HTML解析器。 我们在几个小时内用几行代码就只用了200条就做到了。 我决定在
GitHub上与公众分享结果
使用ng-template库非常简单:
从npm安装依赖项
npm install --save @quanterion/ng-template
或通过纱线
yarn add @quanterion/ng-template
并按如下所示使用它:
import { compileTemplate, htmlToElement } from '@quanterion/ng-template'; async test() { let data = { name: 'Roman' }; let element = htmlToElement(`<div>{{name}}</div>`); await compileTemplate(element, data); alert(element.outerHTML); }
支持的语法
- 具有访问变量和调用函数功能的表达式{{expression}}
- Ng模板
- Ng容器
- 条件* ngIf + * ngIf为
- 周期* ngFor
- 样式[style.xxx] =“值”和[style.xxx.px] =“值”
- 条件类[class.xxx] =“值”
- 具有自动订阅值(作为异步管道)的Observables {{name $}}
有关更多详细信息,请参见
ng-template.spec.ts测试。
使用评估
要评估模板中的表达式,可以将eval与首选项和妓女一起使用。 事实是,在Angular模板中,使用变量访问时没有通常的JavaScript前缀。 因此,您需要调用eval(),它具有作用域中数据对象的所有变量。 我没有成功为eval()生成这样的代码,因为 查看代码
const data = { a: 1, b: () => 4 }; const expression = 'a+b()'; eval('a =1; b = ??;' + expression);
不允许传递函数
通过创建一个函数来找到解决方案,该函数的参数具有带有数据的对象的字段名称:
const data = { a: 1, b: () => 4 }; let entries = [] for (let property in data ) { entries.push([property, data[property]]) } const params = entries.map(e => e[0]); const fun = new Function('code', ...params, `return eval(code)`); const args = entries.map(e => e[1]); const expression = 'a+b()'; const result = fun.call(undefined, expression , ...args);
PS:我希望将来,当新的Ivy编译器的API稳定下来时,将有可能为Ivy生成一组运算符并创建动态的成熟组件!
链接到源