在 angular 2 中支持类似 JSX 的模板会很酷。JSX 可以保存在运行时生成 DOM 所需的所有必需信息。 以下是 JSX 给 angular 带来的一些好处:
同意这对于喜欢 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 次。 这些类型的错误非常常见,类型安全模板支持有很大帮助。
谢谢@robwormald我很感激!
我从不喜欢 JavaScript 中 XML 的想法。 我能看到的唯一好处是模板 HTML 字符串的静态分析。 不过,可以编写静态分析器来分析这些 HTML 字符串。 您可以使用标记函数标记模板字符串,例如
html`<div>...</div>`
或者以某种方式使用 TypeScript 类型系统来提示字符串是 HTML...
我喜欢 templateJsx。
+1 模板Jsx
@mohsen1 “我从不喜欢我的 JavaScript 中的 XML 的想法”:
此问题正在 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 方法的另一个巨大好处:它的功能性质:
我认为“作为函数的模板”与“类似 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 还可以消除提供directives
和selector
。
@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 中。 我认为值得一提的是,将*ngFor
与items.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
我真的不明白为什么 Angular 开发人员反对市场上可用的各种模板语言。 我们拥有的越多越好,特别是如果它像 JSX 这样经过深思熟虑、功能强大且与 TS 兼容的东西。
如果 JSX 发生并且可能会大受欢迎,一些人将继续使用 NgJs 的 HTML 模板,一些人将跳槽并将他们的应用程序迁移到 JSX。 这里的问题在哪里? 绝对无处可去,在我看来。
@Inlesco ......不确定这是真的。
我们拥有的越多越好...
@Inlesco可能JSX
是React
的签名,而Html
是Angular
的签名之一。
我有一个带有动态下拉菜单的组件,我想从子组件(上下文菜单)中配置它。 这是使用 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 并使用
<ng-container *ngTemplateOutlet="element1"></ng-container>
我唯一需要测试的是元素 ID 是否在全局范围内可用,而无需禁用默认组件封装。
更新:它有效......!
并不是说我反对人们寻求帮助,而是@mitevdev的问题与 Angular 中对 JSX 的支持问题几乎没有直接关系。 留在主题上会很好。
@John0x “现在有没有第三方库可以做到这一点?”
我的 google-fu 已经打开了这个当前的实验库:ng-vdom。
我还没有测试过它,但它声称在 Angular 中使用 JSX 提供对 React 风格的 render() 方法的支持
这个问题的最佳解决方案是使用 React。
最有用的评论
请参阅下文,了解 _实际上是 HTML_ 的键入 HTML,即将在您附近的 Angular 中出现