Angular: 类似 JSX 的 angular 模板

创建于 2015-11-04  ·  65评论  ·  资料来源: angular/angular

在 angular 2 中支持类似 JSX 的模板会很酷。JSX 可以保存在运行时生成 DOM 所需的所有必需信息。 以下是 JSX 给 angular 带来的一些好处:

  1. 类型安全以在编译时捕获错误
  2. 更好的运行时性能。 无需在运行时解析模板字符串。 DOM 信息和 AST 可以在编译时序列化
  3. Typescript 已经支持 JSX 并且理解语法
  4. 处理模板时对 IDE 的更多智能和更轻松的重构支持
  5. 可以与 React 共享组件模板

最有用的评论

请参阅下文,了解 _实际上是 HTML_ 的键入 HTML,即将在您附近的 Angular 中出现

所有65条评论

同意这对于喜欢 JSX 的人来说可能很好,但它必须是一个外部贡献者,而不是核心团队,因为其中大部分是意见而不是利益。 我的想法:

1 & 4:可以很好地与 Angular 2 模板配合使用。 已经在 WebStorm 中演示了这一点。 很快就会出现在其他 IDE 中。

2:Angular 的性能可能比 JSX 好,因为编译是作为构建步骤进行的(即将推出)。

5:是的,这可能很好,并且对于使用 Flux 样式数据流的人来说效果很好。 然而,原生 Angular 2 中可能很快就会有更多组件,因此不确定对生态系统的实际好处。

一般来说,我们喜欢符合 HTML 规范的模板,因为所有工具都可以使用它们,设计人员可以更轻松地与它们交互。

@bradlygreen @malekpour
我认为,今天在某种程度上,您可以使用 TypeScript 无缝桥接这两种技术来做到这一点。 最后它只是 JavaScript ......

我在这里有一个示例,我将基于 Flux/React 的组件集成到 Angular 2.0 组件中:
http://www.syntaxsuccess.com/angular-2-samples/#/demo/react

这里还有一些更多细节:
http://www.syntaxsuccess.com/viewarticle/integrating-react-with-angular-2.0

@bradlygreen我同意你几乎所有的观点。 我并不是要更改当前 Angular 2 设计中的任何内容或删除我非常喜欢的运行时模板解析。 为了澄清我的意思,请比较这两个组件:

@Component({
  selector: 'key-up',
  template: `
    <div>    
      <h4>Give me some keys!</h4>
      <div><input (keyup)="onKey($event)"><div>
      <div>{{values}}</div>
    </div>
  `
})
class TestComponent {
  values = '';
  onKey(event) {
  }
}
@Component({
  selector: 'key-up',
  templateJsx: (
    <div>
      <h4>Give me some keys!</h4>
      <div><input (keyup)={ onKey($event) }><div>
      <div>{{values}}</div>
    </div>
  )
})
class TestComponent {
  values = '';
  onKey(event) {
  }
}

虽然第一个模板中的 onKey 是另一个多行字符串中的双引号字符串,但在 JSX 模板中它是一个标识符,它更有意义。

此外,编译器会生成与此类似的内容,我强烈怀疑是否有任何解析器在运行时可以执行得比这更好。 create将有 3 个参数,标签/指令名称、属性和子项。

AngularJsx.create("div", null, 
  AngularJsx.create("h4", null, "Give me some keys!"), 
  AngularJsx.create("div", null, AngularJsx.create("input", {keyup:  onKey($event) })), 
  AngularJsx.create("div", null, {values})
)

我不知道您在评论中提到的计划(第 2 条),但如果 angular 支持编译模板,那就更好了。 所以 JSX 编译器会输出相同的结果。

并且不要忘记,这对于反应社区成员做出贡献或迁移将是一个很大的吸引力。

这很有趣,我从https://angular.io/docs/ts/latest/guide/user-input.html页面随机复制了上述组件片段。 只有当我尝试编译 JSX 模板时,我才意识到<div><input (keyup)="onKey($event)"><div>行中的div元素没有关闭。
https://github.com/angular/angular.io/blob/master/public/docs/_examples/user-input/ts/src/app/app.ts#L36
文档团队在该页面中重复了这个错误至少 4 次。 这些类型的错误非常常见,类型安全模板支持有很大帮助。

@malekpour您可能想查看模板编译器的设计文档 - 它输出的代码与 JSX 不同: https ://docs.google.com/document/d/11r8IuS4xDyhVSEBp7fDYo7aiLYsLEXKs4lPd36umUGM/edit

也就是说,您当然可以将其实现为 3rd 方渲染插件 - 事实上,我们有一个 react-native 渲染器可以让您入门: https :

顺便说一下@thelgevold超级酷的演示——你的组件页面很棒!

谢谢@robwormald我很感激!

我从不喜欢 JavaScript 中 XML 的想法。 我能看到的唯一好处是模板 HTML 字符串的静态分析。 不过,可以编写静态分析器来分析这些 HTML 字符串。 您可以使用标记函数标记模板字符串,例如

html`<div>...</div>`

或者以某种方式使用 TypeScript 类型系统来提示字符串是 HTML...

我喜欢 templateJsx。

+1 模板Jsx
@mohsen1 “我从不喜欢我的 JavaScript 中的 XML 的想法”:

  • 不要将 XML 放入 JavaScript,将其保存在单独的文件中。 但是,将它键入包括所有 Atom 或 Visual Studio IDE 的好处:查找所有符号引用、重命名符号、语法突出显示、自动缩进等。
  • 当 CSS 设计器不小心破坏了您在 HTML 模板中的 JavaScript 片段时,Typescript 编译器会通知您。
  • 等等。

此问题正在 Typescript 项目中解决,请参阅 #7100 中的@MikeRyan52评论。

使用 TypeScript 时,模板是强类型 (TSX),这有助于防止错误并提供更好的开发体验 I :+1: 对于 TSX 模板支持!


:笑脸:

与政治家不同,我不怕说我改变了对 JSX 的看法!

在我最近的 React 项目中,使用 TypeScript 和 JSX (TSX) 是一种乐趣。 类型化的 HTML 真的很棒!

请参阅下文,了解 _实际上是 HTML_ 的键入 HTML,即将在您附近的 Angular 中出现

这很棒。 这也可以通过 templateurl 在链接的 html 模板中实现吗?

我不明白另一个问题的结束。 这更像是打字的东西而不是 jsx 的东西?

@robwormald这比 jsx 好。

TSX 和一般 JSX 的好处不仅限于编辑器智能感知和语法着色。

我个人喜欢 JSX 自然地消除运行时解析和 AST 生成的方式,与当前的 Angular 2 模板解析甚至未来的构建时模板编译相比。

请不要忘记jsx !== React ,它只是由 React 团队发明的。 我认为 Angular 团队可以支持这一点,作为 React 社区迁移的动力。 这是提议的 JSX 规范https://facebook.github.io/jsx/

我喜欢 TypeScript 可扩展性的发展方向,我可以看到有一天 typescript 删除所有 JSX 内容并将其移动到扩展中。 我在上面提到的问题上看到的实际上比 JSX 好。 JSX 有它自己的陷阱,比如class关键字冲突等等。 我确信打字稿团队正在做的事情会变得更好,我们不应该真的要求 Angular 团队支持 JSX。

@mohsen1我同意 TypeScript 可扩展性非常酷,但为什么

我们不应该真的要求 Angular 团队支持 JSX

@malekpour因为它可以在编程语言级别解决?

@mohsen1你是对的,它可以在编程语言级别解决。 事实上,它已经被 TSX 解决了,并且现在被 TypeScript 支持了一段时间。

无论 TypeScript 扩展性如何在开发时提供帮助, template值类型仍将是string ,需要在运行时进行解析和分析,但templateJsx值将保留准备好使用对象或函数。

模板的值类型将保留需要在运行时解析和分析的字符串

这不是真的。 已经有一个 PR 打开,它将编译模板作为构建步骤的一部分,而不是在运行时https://github.com/angular/angular/pull/7155

这不是真的。 已经有PR了...

@MikeRyan52所以,除非您在额外的构建步骤中对模板进行后编译,否则就是这样。

我不完全知道 TypeScript 可扩展性将如何与 Angular 一起工作,但我希望它会比 TSX 更好。 我在 TSX 遇到的两个问题,我认为新提案将解决:

  • 不再是className而不是class
  • 允许在模板中使用<Type>语法。 目前在 TSX 中不可能做return (<div>{(<Foo>bar).baz}</div>)类的事情

在 TSX 中,您可以使用(bar as Foo).baz而不是(<Foo>bar).baz

这 10 行 jsbin 显示了 TSX 模板的工作方式
http://jsbin.com/yodiwid/edit?js ,输出

是的,我知道这一点。 谢谢你的要点!

也许我错过了一些东西 - 在这种情况下,抱歉以下...

在我看来,Angular 运行时必须同时分析模板字符串和模板Url 文件才能合成组件树。 “分析”意味着将字符串转换为任何 JavaScript 表示(对象树或类似的东西)。

TSX(在编译时由 TypeScript 解析为 JavaScript 对象树)可能是 Angular 模板的另一种表示。 也许我错了,但解决 Microsoft/TypeScript#6508 问题肯定比使用 JavaScript 对象树作为另一个 Angular 模板表示困难得多。 除了,
Microsoft/TypeScript#6508不是一个理想的解决方案,它只解决了一些问题(重构、智能感知等)。 我没有解决 JSX/TSX 方法的另一个巨大好处:它的功能性质

  • “模板即功能”开启了其他模板化的可能性
  • 它不受 Typescript 的约束

我认为“作为函数的模板”与“类似 JSX 的 angular 模板”有点不同,所以我创建了新的 #7339 问题。

Angular 2 在 Typescript 上的定位(连同“Angular - 一个框架”的概念)是我离开 React 转向 Angular 的主要原因之一。 我现在唯一缺少的是严格类型化的功能模板。

感谢@malekpour提供了许多支持 TSX/JSX/功能模板思想的优秀论据。 我相信 Angular 团队会听取他们的意见。

@bradlygreen ,我在哪里可以找到更多关于:
“2:Angular 的性能可能比 JSX 更好,因为编译是作为构建步骤进行的(即将推出)。”

编译后的模板会是什么样子?

我的兴趣与模板中存在条件逻辑时 E2E 测试的代码覆盖率有关。
与已编译的 JSX 不同,使用基于 Angular 1.x 字符串的模板,无法确定是否所有代码路径都已执行。

最终目标是能够以 100% 的覆盖率运行一套 E2E 测试并删除未使用的样式。
https://github.com/addyosmani/grunt-uncss

当我完成我的第一个中型 ng2 应用程序时,才意识到 Jsx 还可以消除提供directivesselector

@malekpour见#7339:“JSX ......这不是(Angular)团队有兴趣支持的东西”。

Angular 的性能可能比 JSX 好,因为编译是作为构建步骤进行的

好像 JSX 也不是构建步骤……

@cmelion好吧,我们只需要看看。 :) 前半部分将在几周内登陆。 当它发生时,我们会做大事。

另请参阅http://angularjs.blogspot.com/2016/03/why-angular-renders-components-with.html了解为什么我们喜欢模板而不是 JSX 风格的东西。

+1:+1: templateJsx

来自 React 并研究 ng2,我必须说 JSX 能够使用原生 JS 进行循环等是一个杀手级功能。 获得编译错误也很关键。 出于某种原因,运行本教程并在模板中打错字不会引发任何异常。 不在运行时或编译时。 你只剩下 HTML 渲染出一些代码??

坐在一个模板语言写 *ngFor="let hero of heros" over heros.map(hero => ...); 只是不那么直观。 有 JS/TS 可供您使用是更好的选择。

在您实际编写 HTML 的意义上,模板更好。 我真的很喜欢这样,因为我不必学习 className 与 class。 模板在这里闪耀。

@robwormald :花哨的编辑器支持有什么更新吗? 我正在使用 VScode 并且刚刚尝试了 Atom,但它们似乎都没有具有丰富的 html + ts 自动完成功能的良好模板体验。 Atom 确实很好地突出显示了 HTML 模板字符串。 这也适用于单独的 HTML 文件吗?

我真的很喜欢打字稿和 rx。 拥有 webcomponent 架构也是一个加分项。 但我不想使用 ng-for 之类的东西,比如当前在模板中的东西。 JSX 好得多,因为它只使用 javascript。

所以对我来说,现在没有 jsx 是一个障碍。 我相信很多人都有同样的感觉。

[更新]
我想我错了。 使用 ng 编译器,您基本上可以获得相同类型的功能。
我仍然不喜欢 ng-for 指令,但在阅读了 robwormald 的声明后,我现在明白了其中的原因。

另一个 React 和 JSX 爱好者插话说:关于 NG2 的一切都很好,直到出现带有 onClick、onBlur 和其他 ev 的自定义属性的“老式”HTML 模板。 处理程序、基本地图功能等。

我想问 - 为什么? 为什么 NG2 模板必须包含一些模糊的类似 HTML 的属性来接受字符串来运行循环? 为什么是 ev。 处理程序必须有某种前缀? 为什么它不能与前端开发人员使用的常用 HTML 保持一致?

看看 JSX。 这很简单。 它具有非常干净、平易近人且定义明确的语法。 范围通过正确使用大括号非常清楚地定义。 这是普通的JS。 它不会像 NG2 模板那样尝试重新发明轮子。

说到设计师修改渲染内容的难易程度(HTML vs JSX),根据我的经验,如果设计师有能力,他很容易解释 JSX 是如何工作的,而不是所有奇怪的 *ngIf 等。 HTML attrs .

就我个人而言,JSX 显然是这里的赢家。 当然,这是有争议的,这是一个普遍的习惯问题,但至少双方都可以说出来,比较一下:)

@Inlesco只需要注意,我发现设计师不太可能有更好的时间修改包含 JS 的 JSX 模板,而不是包含*ngFor的 HTML。

@gioragutt一位设计师发现很难修改 Android 应用程序的 xml 模板。 这不是使用 html 构建 android 应用程序的正当理由

@m3l7考虑一下:

嘿马特,你能帮我对齐trade-form.component.html的文本框吗?

相对

嘿马特,你能帮我对齐TradeFormComponent.tsx的文本框吗? 是的,只要寻找渲染函数,不要忘记你必须使用className而不是 class

等等。 当然,这是自以为是,我并不是说一种方法绝对优于另一种。 与我总是从 React 开发人员那里听到的不同: Ha we do data.map(...) so it's so much better than *ngFor 。 这没什么意思。 无论哪种方式,你都会搞砸的。 今天选择React不是Angular或相反的唯一原因 - 是人们的意见。 如果你/你的 CEO/你的首席技术官/任何喜欢 React 多过 Angular 的人,你都会去做 React。 反之亦然。

这也意味着所有其他框架/库。 所有这些Vue / Aurelia或其他几十个框架。 谁需要那个狗屎。 社区应该挑选一些好的(又名React / Angular )并改善他们的生活。 发布所有这几十个图书馆不会有任何进展。

@gioragutt这不是意见。 模板中的类型检查是向前迈出的一大步。

对于第二点:正确,这就是为什么许多人采用 angular 并尝试改进它(即通过添加 jsx/tsx)

@m3l7是的,类型检查很重要,并且在带有 typescript 语言服务的 Angular 模板中是可能的。 另一方面,在模板中具有无限的表现力会阻碍工具支持并具有其他含义,例如一个人可能需要花费多少精力来理解模板文件。 对于是否值得拥有相同语言的力量和一致性,人们可以有意见。

@m3l7正如@egaga所说,您可以在 html 模板中进行类型检查、linting 和验证。 事实上,这在今天内置于 angular 中。 我认为值得一提的是,将*ngForitems.map(item => ...)可能不值得,对于*ngIf ,因为它背后的东西不仅仅是for遍历一个集合,比如map

另外,例如: pipes 。 使用管道有多容易,它的表现力如何以及它与模板的集成度如何。 作为一个每天使用 linux 和 bash 的人, pipes的概念是如此清晰和直观,更不用说可组合了。 在纯 JS 中需要更多的时间来做到这一点。

见 - https://github.com/angular/vscode-ng-language-service

我们在这方面的立场没有改变,也不太可能改变。 当然,欢迎您将 React 或任何基于 JSX 的库集成到 Angular 中,因为自己做很简单。 我们不会在 Angular 核心中支持这一点。

然后你就打开 Vue 的市场

@robwormald我们需要一种将强类型 html 与

@bradlygreen请让它发生,如果发生这种情况,angular 会有很多好处

目前是否有任何第三方库可以完成此操作?

@John0x在没有原生功能/选择的情况下使用 angular 会适得其反:rose:

请让这发生:)

人们实际上使用className参数来否定 JSX 的好处这一事实是可笑的。 在我看来,这个问题是 Angular 作为前端框架在开发者体验方面最大的失败,而这种自满只会让 Angular 越来越多地被其他主要框架所取代。

@KamiShikkaku ......如果你非常喜欢 JSX,你可能对@trotyl介绍的 NG-VDOM
https://blog.angularindepth.com/introducing-to-ng-vdom-a-new-way-to-write-angular-application-60a3be805e59

让我们不要忘记这一点
https://github.com/angular/angular/issues/21224

我真的不明白为什么 Angular 开发人员反对市场上可用的各种模板语言。 我们拥有的越多越好,特别是如果它像 JSX 这样经过深思熟虑、功能强大且与 TS 兼容的东西。

如果 JSX 发生并且可能会大受欢迎,一些人将继续使用 NgJs 的 HTML 模板,一些人将跳槽并将他们的应用程序迁移到 JSX。 这里的问题在哪里? 绝对无处可去,在我看来。

@Inlesco ......不确定这是真的。

我们拥有的越多越好...

@Inlesco可能JSXReact的签名,而HtmlAngular的签名之一。

我有一个带有动态下拉菜单的组件,我想从子组件(上下文菜单)中配置它。 这是使用 React 的 5 分钟,那么 Angular 呢?

@mitevdev ...具有动态下拉列表的组件通常具有带有其配置的输入。 不确定子组件(上下文菜单)是什么以及为什么它是下拉组件的子组件。

有一个组件 A(父),它是组件 B(子)的包装器。 A 有一个工具栏,可以由组件 B 自定义。 B 有许多不同的实现,但 A 始终保持不变。 该工具栏的内容可能会随着 B 的实现而变化。

当然,我可以“预测”所有可能的组合并使用 *ngIf 或 *ngSwitch 但这并不优雅,好像组件 B 也可以发送配置为视图和回调处理程序的内容(元素)(这正是 React支持)。

@mitevdev我认为<ng-content> / slots应该适用于您的情况,它的作用类似于 React 中的props.children

@khaledosman好点,寻找<ng-content>我发现<ng-container>*ngTemplateOutlet ,这似乎是我的情况的解决方案。

背后的想法是在子组件 B 中定义工具栏的元素:

...
<ng-template #element1>...</ng-template>
...

组件 A 获取该元素的 ID 并使用渲染 B 中定义的元素。

<ng-container *ngTemplateOutlet="element1"></ng-container>

我唯一需要测试的是元素 ID 是否在全局范围内可用,而无需禁用默认组件封装。

更新:它有效......!

并不是说我反对人们寻求帮助,而是@mitevdev的问题与 Angular 中对 JSX 的支持问题几乎没有直接关系。 留在主题上会很好。

@John0x “现在有没有第三方库可以做到这一点?”

我的 google-fu 已经打开了这个当前的实验库:ng-vdom。

我还没有测试过它,但它声称在 Angular 中使用 JSX 提供对 React 风格的 render() 方法的支持

https://blog.angularindepth.com/introducing-to-ng-vdom-a-new-way-to-write-angular-application-60a3be805e59

https://github.com/trotyl/ng-vdom

这个问题的最佳解决方案是使用 React。

由于不活动,此问题已自动锁定。
如果您遇到类似或相关的问题,请提交新问题。

阅读有关我们的自动对话锁定政策的更多信息。

_此操作已由机器人自动执行。_

此页面是否有帮助?
0 / 5 - 0 等级