强调向后兼容性

时间:2013-01-08 03:46:12

标签: backbone.js underscore.js

我正在尝试使用一个新版本的下划线(1.2.0)制作的骨干应用程序,这个应用程序在更新的rails应用程序中加载了更新版本的下划线(当前附带的下划线)版本的backbone-on-rails gem),所以这是一个向后兼容性问题,即使在更新日志http://underscorejs.org/#changelog的帮助下我也无法弄清楚,但是,当我尝试保存数据时,它正在发生

上下文:

由Companies集合创建的公司正在尝试保存(使用setBucket函数)其包含的Bucket的ID(请参阅下面的代码)。

这是我尝试保存数据时遇到的错误。

错误

<error>
    _.extend
    _.clone
    _.extend.toJSON
    _.extend.save
    _.extend.update
    Backbone.sync
    _.extend.sync
    _.extend.save
    window.Company.Backbone.Model.extend.setBucket
    window.AppView.Backbone.View.extend.createCompanyOnEnter
    jQuery.event.dispatch
    elemData.handle.eventHandle

源代码

...(代码省略)......

  var company = Companies.create({text: text});    #this works. company is created
  company.setBucket(initialBucket.id);    #this triggers the error

....(代码省略)

setBucket: function(bucketId) {
this.save({bucket: bucketId}, {silent: true});   #the function that's not working

1 个答案:

答案 0 :(得分:1)

您可以同时运行两个版本的Underscore。只需在页面上加载您的Underscore版本,然后添加以下行:

var underscore = _.noConflict();

将您的Underscore版本别名为underscore变量(如果您愿意,您当然可以使用其他别名)。然后对所有现有的使用Underscore的代码运行查找/替换,将“_”替换为“underscore”(或您的别名)。

最后,将您的Rails应用及其Underscore版本加载到该页面。它将获得_别名,您的代码可以使用其版本而不会影响您的库版本。

*编辑*

好的,这里有一点背景知识。在Javascript中(就像在Ruby中我认为的那样)函数是第一类对象。这意味着_在技术上不是Underscore函数本身,它只是一个指向“真正的”Underscore函数(它本身就是一个对象)的变量。这也意味着您可以像对待任何其他变量一样为函数创建别名。就像你可以做到的那样:var a = 5; var b = a你也可以做var b = _;然后你可以做b.map()或其他什么。好吧,差不多;因为Underscore保留了对Underscore的内部引用,您需要更新它,这是noConflict的来源;该代码应该是:var b = _.noConflict();

顺便说一句,这也意味着您可以转到另一个方向并根据需要更改__ = alert; _('hello world')

因此,您目前正在发生的事情是您将Underscore引入您的页面。大概是你通过在你的主html.erb文件中放置一个<script src='underscore.js'></script>来做到这一点。这带来了Underscore版本#1。然后你加载你的Rails应用程序;我不确定这是如何工作的,因为它取决于你的应用程序,但不知何故该应用程序在页面上放置另一个脚本标记,指向Underscore版本#2。

这是一个问题,因为Underscore版本#2刚刚替换了您的版本#1(就像我刚才用_替换alert一样)。这会打破你的代码。只需在您的Rails应用中添加<script>标记后,即可修复它。这将恢复版本#1并修复您的代码...但是破坏您应用的代码。

您真正想要的是您的代码使用版本#1和您的应用程序代码使用版本#2。这是我的原始答案所在:通过将_的第1版重新别名为underscore(或其他任何内容),您的Rails应用可以继续将版本#2引用为_,并且您的代码可以继续使用版本#1作为underscore