Backbone 'Reporting Filter' Shared State Example
// Bind Backbone to jQuery (defensive)
if (!Backbone.$ && window.jQuery) Backbone.$ = window.jQuery;
// --- Share-state Backbone example (filters) ---
const stateKey = "bb_filters";
const agentKey = "YOUR_AGENT_KEY";
const agent = window.eucera?.agent?.(agentKey);
const FiltersModel = Backbone.Model.extend({
defaults: { location: "", account: "" }
});
const FiltersView = Backbone.View.extend({
el: "#filters-root",
className: "filters-panel",
template: _.template(`
<label>
Location
<select name="location">
<option value="">Any</option>
<option>NYC</option>
<option>London</option>
<option>Tel Aviv</option>
<option>Remote</option>
</select>
</label>
<label style="margin-left:12px">
Account
<select name="account">
<option value="">Any</option>
<option>Acme Inc</option>
<option>Globex</option>
<option>Initech</option>
<option>Umbrella</option>
</select>
</label>
<pre class="snapshot" style="margin-top:12px"></pre>
`),
events: {
"change select[name=location]": "onChange",
"change select[name=account]" : "onChange"
},
initialize() {
this.listenTo(this.model, "change", this.renderSnapshot);
// Agent -> UI: subscribe for shared state updates
this._handler = (key, nextState) => {
if (key === stateKey) this.model.set(nextState);
};
agent?.shareState(stateKey, this.model.toJSON(), this._handler);
this.render(); // ensure element exists & template rendered
},
render() {
this.$el.html(this.template());
// Sync current values into selects
this.$("select[name=location]").val(this.model.get("location"));
this.$("select[name=account]").val(this.model.get("account"));
this.renderSnapshot();
return this;
},
renderSnapshot() {
this.$(".snapshot").text(JSON.stringify(this.model.toJSON()));
},
onChange(e) {
const $t = this.$(e.currentTarget);
const next = { ...this.model.toJSON(), [$t.attr("name")]: $t.val() };
this.model.set(next);
// UI -> Agent
agent?.shareState(stateKey, next);
this.renderSnapshot();
},
remove() {
agent?.clearState(stateKey);
Backbone.View.prototype.remove.call(this);
}
});
// Mount after #filters-root exists
new FiltersView({ model: new FiltersModel() });
Updated 16 days ago