1

我这里有一种情况,我似乎无法弄清楚。如果有人知道如何解决这个问题,我很想听听建议。谢谢

我有一个在应用程序的子导航栏上可见的“全局视图”,即日历,该日历在整个应用程序中用作全局日历,因此几乎所有视图都使用日历视图和模型来设置显示数据选择的日期。

每次更改日期时,此日历视图/模型应该有某种方式存储在历史记录中,这(我认为)是在每次更改日期时使用单个 URL 或查询字符串参数完成的,例如

webapp/view1?date=20120301

当日期改变时,它就是查询字符串。

我想为此使用查询字符串参数,因此我不必在每条路由上指定 (/:date) 可选参数。

当查询字符串更改时,主干停止触发路由更改或历史事件,它们只是忽略 Backbone.History 实现上的查询字符串,这破坏了我的所有实现,因为每次更改查询字符串时我都无法跟踪,所以“后退”按钮不会触发更改事件,因此我无法更改模型上的日期,这会更改日历上的日期。

我知道一个简单的解决方案就是使用“漂亮的 URL”并将该日期参数添加到每个视图,但我试图避免这种情况。

有什么建议么?提前致谢


更新

我最终使用了 Backbone 文档建议的“漂亮 URL”,因为使用查询字符串会给我带来很多麻烦来跟踪 URL 更改和历史记录,当使用 hashchange 而不是 pushState 时也不会按预期工作。

所以,我的代码最终是这样的:

将路由器、视图、控制器等某处附加到路由器的“路由”事件,以检查日期的 URI 并将此日期设置为日历选择器:

this.listenTo(myRouter, "route", this.routeChanged);

然后,此方法将执行以下操作:

checkURIdateParameter: function (route, arr) {
        var found = false; 
        for (var i = 0; i < arr.length ; i++) {
            if (arr && arr[i] && arr[i].indexOf("date=") != -1) {
                if (app.models.dateControl) {
                    var dateFromParameter = new Date(arr[i].substring("date=".length).replace(/\$/g, ":")); 
                    dateFromParameter = (isNaN(dateFromParameter.getTime())) ? app.models.dateControl.defaults.date : dateFromParameter;
                    app.models.dateControl.set("date", dateFromParameter);
                    found = true; 
                }
            }
        }
        if (!found) app.models.dateControl.set("date", app.models.dateControl.defaults.date, {changeURI:false}); 
    }

这用作从 URI 读取参数并将这些更改反映在 dateControl 上的函数。

应该有另一种方法负责在每次更改日期时将 URI 更新为新的(以便参数与视图同步),并且可以毫无问题地复制和粘贴链接。

在您的路由器、视图、控制器上的某处:

this.listenTo(app.models.dateControl, "change:date", this.updateURIdateParameter); 

这是一个附加到具有当前日期的模型的方法,此模型由日历选择器(UI 控件)或与路由事件链接的方法(routeChanged,见上)更新。

这个方法应该做这样的事情:

, updateURIdateParameter: function (a, b, c) {
        if (c && c.changeURI == false) return; //this is in case i don't want to refresh the URI case the default date is set. 

        var currentFragment = Backbone.history.fragment;
        var newFragment = "";
        var dateEncoded = app.models.dateControl.get("date").toJSON().replace(/\:/g, "$");
        newFragment = currentFragment.replace(/\/date=([^/]+)/, "") + "/date=" + dateEncoded; 

        if (newFragment != currentFragment) {
            app.router.navigate(newFragment, false);
        }
    }

此方法获取从相应模型中选择的 currentDate,对其进行解析,然后从 Backbone.history.fragment 中获取 URL,对其执行一个很好的正则表达式,它将替换旧的日期参数(如果存在),然后附加新的编码日期. 然后以静默模式导航到此路由,以便不调用检查路由的方法(这可以防止烦人的循环)。

我希望这有帮助。

4

1 回答 1

0

我建议使用“漂亮的 URL”。

在此示例中,浏览器栏中的 FYI 页面 URL 将闪烁。

在 Backbone.Router 内部的某个地方:

this.route('*action', function() {
  console.log('404');
});

this.route(/^(.*?)\?date=(\d+)$/, function(route, date) {
  // same current route (with ?date)
  var fragment = Backbone.history.fragment;
  // navigate to main route (to create views etc.)
  this.navigate(route, {trigger:true, replace:true});
  // silent change hash
  this.navigate(fragment);
});

this.route('any', function() {
  // need wait for hash change
  _.defer(function() {
    console.log('parse date here and do what you want', window.location.hash.match(/^(.*?)\?date=(\d+)$/));
  });
});

this.route('route', function() {
  // need wait for hash change
  _.defer(function() {
    console.log('parse date here and do what you want', window.location.hash.match(/^(.*?)\?date=(\d+)$/));
  });
});
于 2013-05-13T18:52:34.967 回答