7

尝试使用 Backbone 的导航属性。

 this.navigate("week/" + companyName + "/" + employeeNo + "/" + weekEnd, { trigger: true, replace: false });

上面的代码执行一次。

它击中了这个:

routes: {
    "week/:companyName/:employeeNo/:weekEnd": "getWeek"
},

然后这个函数被命中两次:

getWeek: function (companyName, employeeNo, weekEnd) {
    console.log('getWeek:', companyName, employeeNo, weekEnd);
 }

它在 Firefox 中记录了两次,在 IE 和 Chrome 中只记录了一次。

这里有什么问题?我最初甚至没有将触发器设置为 true,Firefox 忽略了它并仍然触发了 URL。

4

3 回答 3

6

我最近遇到了类似的问题,Firefox 在 Backbone.navigate 之后进行了两次服务器调用。就我而言,这是因为我们没有对字符串进行编码。您的公司名称是否有任何需要编码的字符?

你可以试试:

this.navigate("week/" + escape(companyName) + "/" + employeeNo + "/" + weekEnd, { trigger: true, replace: false });
于 2013-08-23T15:39:23.143 回答
4

当我遇到同样的问题并在这里解决根本问题时介入。

正如大家之前提到的,问题来自于 URL 编码。现在关于为什么这个问题只出现在 Firefox 中......

让我们首先快速总结一下当哈希变化时路由是如何被调用的。这里有3个关键功能:

  • loadUrl:此函数将调用您的路由处理程序。
  • 导航:这是用于手动更改路线的功能。如果触发标志设置为true,该函数将调用loadUrl
  • checkUrl:此函数设置为窗口对象上onhashchange事件的回调(当然,当它可用时)。它还在某些条件下运行loadUrl 。

现在,我们进入了有趣的部分。

当您运行navigate时,Backbone 将缓存您导航到的片段。哈希更改,checkUrl也将被调用。然后,此函数将检查缓存的哈希值是否等于当前哈希值,以免在您之前调用navigate时不执行loadUrl,因为这意味着它已经被调用过。为了进行比较,checkUrl使用函数getFragment获取当前哈希,该函数使用getHash。这是getHash的代码:

getHash: function(window) {
  var match = (window || this).location.href.match(/#(.*)$/);
  return match ? match[1] : '';
},

你有你的问题。location.href在 Firefox 中是 URI 编码的,但不是在 chrome 中。因此,如果您导航到另一个散列(带有或不带有触发标志),在Firefox 中,Backbone 将缓存您的散列的未编码版本,然后将其与编码版本进行比较。如果您的哈希包含一个应该编码的字符,则比较的结果将是否定的,并且 Backbone 将执行它不应该执行的路由处理程序。

根据解决方案,人们之前说过,你的 URI 应该被编码。

于 2014-09-15T13:16:35.297 回答
0

问题可能很老,但对我来说这仍然是相关的。在我的情况下,编码 url 是不够的。我将 Backbone 中的 GetHash() 函数替换为:

getHash: function (t) { 
    var e = (t || this).location.href.match(/#(.*)$/);
    return match ? this.decodeFragment(match[1]) : '';
}
于 2018-04-04T14:55:27.033 回答