实现location.hash双向绑定到AJAX记录上下文

时间:2014-07-14 22:17:02

标签: javascript jquery ajax hashchange

我有一个简单的javascript AJAX应用程序,允许搜索和选择记录。选择更新location.hash并加载相关的记录详细信息,理想情况下也相反(在哈希更改时加载记录)。当然,粗心的实现会导致循环和额外的面板闪烁。

我想要一个可预测且简洁的双向绑定实现。

一种方法是仅在hashchange事件上加载记录,并且在UI中选择记录时,设置location.hash。这看起来最简洁,但我担心这会在使用轮询的hashchange垫片的旧版浏览器中降低记录点击响应速度。

另一种方法是在选择记录时记录navigating(例如)状态,并在处理hashchange时清除它。 this question中涵盖了这些内容。但是,这似乎是某些事件序列,例如快速多次点击Back,可能会导致显示的内容和URL之间出现不一致。

您是否看到过解决这些问题的实现?

2 个答案:

答案 0 :(得分:1)

为什么不使用HTML5 history API呢?所有现代浏览器都支持它

为了简化操作,您可以使用history.js library来处理历史记录/状态API

使用该库,您可以订阅URL更新

History.Adapter.bind(window, 'statechange', function () {
    // event handler code here
    var state = History.getState();
}

或将新网址推送到历史记录

History.pushState(null, "name", "http://newurl");

我不确定您希望使用哪个JS框架来获得双向绑定,但使用KnockoutJS,您可以使用读取和写入方法创建ko.computed对象

答案 1 :(得分:0)

我认为在我的案例中有一个简单的答案,因为它是一个只读/幂等操作(好吧,它实际上记录了一个视图)。

我只会存储当前内容显示的状态,并在每个会加载内容的事件(包括'冗余' hashchange事件)上对其进行测试,忽略该事件如果它与当前显示的状态匹配。

看起来便宜,无论好坏。 :)

这是我的近似/伪代码:

var activeRecordId;
function loadHash() {
    var idList = window.location.hash.substring(1).split(',');
    if (idList.length > 1) loadSpecificRecordsToList(idList);
    else if (idList != '') loadDetailRecord(idList[0]);
}
function loadDetailRecord(id) {
    if (id != activeRecordId) {
        activeRecordId = id;
        doDetailLoadAjaxAndSuch(id);
    }
}
$(function () {
    loadHash();
    $.bind('hashchange', loadHash);
});