1

I have a simple javascript AJAX application that allows search and selection of records. Selection updates the location.hash and loads the associated record detail, and ideally vice-versa also (loading a record when the hash changes). Of course a careless implementation can cause loops and extra panel flashes.

I want a predictable and concise implementation of this bidirectional binding.

One approach is to only load a record on the hashchange event, and when a record is selected in the UI, set location.hash. This seems most concise, but I'd be concerned this would diminish record-click responsiveness in older browsers with a polled hashchange shim.

Another approach is to record a navigating (e.g.) state when selecting a record, and clear it when handling hashchange. That's covered in this question. However, that seems like certain event sequences, like tapping Back multiple times rapidly, might result in inconsistency between the displayed content and URL.

Have you seen an implementation that solves these problems?

Community
  • 1
  • 1
shannon
  • 8,664
  • 5
  • 44
  • 74

2 Answers2

1

Why not to use HTML5 history API instead? All modern browsers support it

To make things easier you can use history.js library to work with History/State APIs

Using that library you can subscribe to URL updates

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

or push new URL into history

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

I'm not sure which JS framework you would like to use to get bidirectional binding, but with KnockoutJS you can create ko.computed object with read and write methods

Maksym Kozlenko
  • 10,273
  • 2
  • 66
  • 55
  • The problem is exactly the same, yes? How does a client that doesn't support `History` (including IE9) respond to selection of a record? – shannon Jul 15 '14 at 15:31
  • "On 26 February 2013, Internet Explorer 10 was made available for download to all Windows 7 SP1 users." - http://en.wikipedia.org/wiki/Internet_Explorer_10 So, especially in light of how badly Windows 8 sucks (and is avoided), I think disabling core functionality on IE9 is a bad choice. – shannon Jul 15 '14 at 15:38
  • But maybe I don't understand what you are suggesting? – shannon Jul 15 '14 at 15:39
  • Library has fallback to hashtag for older browsers – Maksym Kozlenko Jul 15 '14 at 22:51
  • +1 for the recommendation to use newer technology, but note the problem is still the same, since in the fallback case it uses the technology referenced in the original question. It's one thing to "downgrade" non-essential features in older browsers, but to determine they cannot click detail links at all is a no-go for me. – shannon Jul 18 '14 at 16:45
0

I think there's a simple answer in my case, since it's a read-only/idempotent operation (well, it actually logs a view).

I'll just store the state displayed by the current content, and test it on each event that would load content (including the 'redundant' hashchange events), ignoring the event if it matches the currently-displayed state.

Seems cheap, for better or worse. :)

here's my approximate/pseudo-code:

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);
});
shannon
  • 8,664
  • 5
  • 44
  • 74