使用Express Handlebars和Angular JS

44

背景

我正在建立一个使用NodeJS作为服务器,Express Handlebars(仅在服务器端使用的Handlebars),并希望在客户端使用AngularJS的网站。


问题

AngularJS和Handlebars使用相同的模板语法
{{foo}}
这会导致AngularJS代码被Express Handlebars先解释,然后抛出错误,因为它尝试提取的数据只存在于Angular而不是Node中。


问题

有没有办法让AngularJS和Express Handlebars共同工作?


可能的解决方案

  • 更改AngularJS的语法
    • 我正在研究BackboneJS,看起来可以更改语法。AngularJS可能也有类似的东西。
  • 在Express Handlebars中创建一个ng助手。
    • 它将返回其未解析的内容。但是我无法弄清楚如何做到这一点。

为什么你在服务器端使用Handlebars而不是Jade或EJS?Handlebars/Angular在客户端上表现最好。 - jwimmer
3
Handlebars在客户端的优势是什么?除非有什么特别的原因,否则这并不意味着不能在服务器端使用 Handlebars。 - Jake Berger
5个回答

73

你的第一个解决方案是可行的,AngularJS允许像这样更改文本插值的起始/结束符号:

您的第一种解决方案是可行的,AngularJS允许更改文本插值的起始/结束符号,例如:

appModule.config(function($interpolateProvider) {
  $interpolateProvider.startSymbol('{[{');
  $interpolateProvider.endSymbol('}]}');
});

那么你可以在你的模板中使用它:

<div>{[{message}]}</div>

同时参见:$interpolateProvider文档

希望这可以帮到你。


对我来说没有起作用。我正在使用他们使用//作为新标记的文档。当我这样做时,它只会在我的页面上显示原样。所以像这样的东西:<h1>Hello //name// </h1> 在页面上显示为Hello //name//。 - codeinprogress

18
您可以始终使用ng-bind语法:

<p ng-bind="user.profile.description"></p>
这与
<p>{{user.profile.description}}</p>
相同。

从Angular文档的ngBind部分:

通常,您不会直接使用ngBind,而是使用双花括号标记{{ expression }},它类似但更简洁。

如果模板在Angular编译之前由浏览器原始显示,则最好使用ngBind而不是{{ expression }}。由于ngBind是一个元素属性,因此当页面正在加载时,它将使绑定对用户不可见。


但是,这个评论的重点不是在第一句话中概括了吗?“通常情况下,你不会直接使用ngBind”。ngBind旨在用于处理模板内容闪烁(FOUC)的情况。我会谨慎地遵循文档的建议,并且这似乎非常明确地建议只在这些情况下使用它。我更倾向于这篇文章的被接受答案。 - dudewad

14
为了保持AngularJS风格,你的第二个解决方案更好,在Express Handlebars中创建一个helper。参考Handlebars网站:http://handlebarsjs.com/block_helpers.html,您可以注册一个raw-helper helper。
Handlebars.registerHelper('raw-helper', function(options) {
    return options.fn();
});

将其放入四重花括号{{{{中,然后在您的hbs模板中使用它。

{{{{raw-helper}}}}
<div class="container" ng-controller="AppCtrl">
    Total Members: {{members.length}}
</div>
{{{{/raw-helper}}}}

1
这是比被接受的方案更好的解决方案,因为它意味着您不会偏离标准的Angular双括号约定(您的Angular代码更模块化,可在其他项目中使用)。 - wayfarer_boy
1
我更喜欢这个解决方案。我唯一做的改变是将我的辅助程序称为angular-js - 对我来说,{{{{angular-js}}}} 更好地解释了它的目的。 - steverus_snape

11

有一种更好的方式:\{{foo}}。 Handlebars内容可以通过两种方式进行转义,即内联转义或原始块辅助程序。通过在mustache块前缀加上\创建内联转义。使用{{{{ mustache大括号创建原始块。您可以在此处查看http://handlebarsjs.com/expressions.html#helpers


9
我建议使用AngularJS的数据绑定语法(类似于Handlebars),并让您的NodeJS服务器简单地提供静态的AngularJS源代码。我更喜欢将模板转移到客户端,从而减轻服务器的压力,更不用说AngularJS和其他MVC框架(我最喜欢的是EmberJS)非常适合动态构建网页。
我是Yeoman的粉丝,这里有一个生成器可以构建由NodeJS提供的Angular项目:https://github.com/yeoman/generator-angular

3
我认同MV*框架在动态构建网页方面非常出色,但是我认为页面特定部分应该以编译方式提供。任何可能通过用户交互而改变的内容 -> 使用客户端模板。 - Jake Berger
另外,如果客户端渲染失败会发生什么?最初提供渲染的模板将使您的页面更易于访问更广泛的受众,更加强大和容错能力。 - Tom Pietrosanti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接