覆盖Backbone导航以获取刷新路由

时间:2014-08-04 04:15:11

标签: backbone.js marionette

这是discussed a lot before,在特定级别上,但我还没有找到一个很好的方法来覆盖将骨干路由导航到同一哈希路由的一般情况。 甚至对why this is a bad idea进行了一些讨论,这就是为什么Backbone won't change their approachdespite lots of requests

具体来说,我有一些在Backbone应用程序中显示数据(在模态/对话框/弹出框中)的实例,可以在不改变路径的情况下关闭它。我继续前进'正确的'在这些情况下手动路径,以便不刷新页面并传统导航。

不幸的是,Backbone has some specific code要避免这种用例,所以我想扩展Backbone以允许这些请求,而不需要任何处理程序响应路径更改的点击次数。也就是说,我希望保持Backbone View的DRY和 manually call a navigate,而只是使用HTML href="#path"

因此,基本上,我尝试创建一个Backbone扩展,将其默认导航方法覆盖到我们自己的导航方法。我发现this example我试图更新但没有成功。除非出现任何加载顺序问题,我觉得它应该可行,但似乎无法触发该代码。

      _.extend(Backbone.History.prototype, {
        refresh: function() {
            this.loadUrl(this.fragment);
        }
    });

    var routeStripper = /^[#\/]/;
    var origNavigate = Backbone.History.prototype.navigate;
    Backbone.History.prototype.navigate = function (fragment, options) {
        var frag = (fragment || '').replace(routeStripper, '');
        if (this.fragment == frag)
            this.refresh();
        else
            origNavigate.call(this, fragment, options);
    };

目前,我已经运行了一些特定的点击处理程序,只有当Backbone没有响应时才会响应,但这并不符合我的代码标准:

AView = Backbone.Marionette.ItemView.extend({
  template: HandlebarsTemplates['a/template'],
  initialize: function (data) {
    ...
  },
  events: {
    'click a[href]': function(event) {
      var routeStripper = /^[#\/]/;
      var new_frag = ($(event.target).attr("href") || '').replace(routeStripper, '');
      if(new_frag == Backbone.history.getFragment()) {
        Backbone.history.loadUrl(Backbone.history.getFragment());
      }
    }
  },
});

有没有人有任何功能模式来解决这个错综复杂的角落?

1 个答案:

答案 0 :(得分:0)

在这个单一问题的3天非常令人沮丧之后,我已经解决了我无法覆盖Backbone.history,由于它奇怪的启动模式,我有限的JavaScript技能并不熟悉OR事实上,我们正在使用Marionette的AppRouter,因为某种原因而无法接收覆盖。

无论哪种方式,这个问题通过手动关闭模态而不导航到非模态散列来表现。这已通过在非模态哈希上手动调用导航并将窗口重新定位到之前的位置(未发现闪烁或可见重绘)来更正。

一些代码:

var scrolled_top = window.parent.pageYOffset || window.parent.document.documentElement.scrollTop;
var scrolled_left = window.parent.pageXOffset || window.parent.document.documentElement.scrollLeft;
App.router.navigate('');
window.parent.scrollTo(scrolled_left, scrolled_top); //reset screen location after navigation sets it to top of new view