使用Backbone.JS处理服务器代码和客户端代码之间的共享常量的最佳方法是什么?例如,假设我有这个用户角色地图:
user_roles = {
1 => "member",
2 => "moderator",
3 => "admin"}
显然,如果您在客户端和服务器端的代码中复制这些定义,则这不能很好地扩展并且容易出错。
我可以想出的解决方案是将这些定义公开为Backbone.Collection或Backbone.Model并从服务器获取它们,但如果你有大量的常量类型,这可能会导致不必要的开销,而且我我不确定它们是否真的属于模型内部。
解决这个问题有哪些不同的解决方案,它们的扩展程度如何?
答案 0 :(得分:12)
我尝试了几种不同的方法来处理这个问题。我不知道他们中的任何一个是否是最好的方式,但两者都对我有用,所以我只是在这里描述它们并希望它们有所帮助。
核心概念在两者中都是相同的:常量在服务器端语言中定义为 true constants (在我的情况下是C#和Java),并且为了好处而转换为JSON或javascript客户。我认为这是要走的路,而不是共享一个JSON / YML /等。配置文件。仅仅因为javascript没有真正的常量并不意味着你的服务器也不应该拥有它们。
选项1:通过Web服务调用在运行时加载常量和枚举。
创建一个服务端点(让我们称之为/enums
),它基本上将所有服务器端枚举和常量收集到一个大块的JSON中。为了避免额外的服务调用,如果您还使用了一些服务器端模板框架,则可以将其引导到index.html
。
如果您不想将任何内容引导到静态内容,则可以执行其他优化。因为常量变化很少,所以可以将/enums
响应包装到包含服务器应用程序构建版本的包装器对象中。例如:
{
"version": "1.2.1.0",
"enums": { ... }
}
当用户第一次点击页面时,请求GET /enums
,并将整个响应存储到浏览器的本地存储中。在后续访问中,从本地存储中读取常量,并使用GET /enums?v=1.2.1.0
请求常量。服务器应将其版本与传递的版本进行比较,如果它们相同,则只返回HTTP 200 OK
以向客户端指示其枚举仍然有效。
如果您在前端和后端开发人员使用不同工具的分布式环境中工作,或者通常不能紧密协作,那么此选项很有用。
选项2:将常量作为构建过程的一部分进行共享
您可以使用文本转换模板(例如T4)从服务器端语言源生成javascript代码。就我而言,这是C#。
我将所有服务器端枚举存储在一个目录中,并运行构建任务,将该目录中的所有C#源文件转换为javascript对象,并将它们合并到客户端源树中的一个文件enums.js
中。 p>
我发现这是一个优选的选项,但是如果客户端和服务器开发没有同步完成(一起构建,一起发布),那么依赖关系管理会变得相当混乱。在我的情况下,我总是将客户端和服务器一起部署,所以这很好。
答案 1 :(得分:1)
如果您的后端不在JavaScript中,请使用您的常量生成JavaScript或JSON文件,然后将其包含在客户端构建中或将其注入初始HTML模板中。我有时使用Django配置设置或使用yaml文件中的设置执行此操作:yaml - > python,yaml - > js或只是JSON。
我不知道为常量设置所有额外的Backbone Model逻辑是否有意义。
另一方面,这是我喜欢meteor.js的一个很好的理由。完全不需要担心这种事情,因为您可以轻松地跨服务器和客户端共享您的常量。 :)