backbone.js - Backbone.Collection.reset() => child view is out of sync with parent -


i have list of items. stored in backbone pageable collection.

they displayed this

|---item1---------------------------|
|---item2---------------------------|
|---item3---------------------------|
|---item4---------------------------|
|---item5---------------------------|
|---item6---------------------------|
|---item7---------------------------|
<< 1,2,3...end >>

user can click on individual item open detail view in separate page. detail view has listeners initialized when it's created. listeners bound item model.

since detail view huge, cache in dom toggling visibility. subsequent click on item toggle cached view.

------ here problem -----

when item list switched page, collection reset (by paginator). , models stored in collection dereferenced , new set of models created. after page switched , forth, opened item has different copy of stored in collection. when change name of item in detail view (in view cache), name in item list not changed.

the views out of sync! because referencing different models.

not sure if else encounter before. if do, please share me how solve it.

thanks much.

the straight-forward way maintain fresh reference between list view items , corresponding detail view, on page change, re-render detail view. i'm assuming options is not acceptable within scope of project.

what do, when have task of forming relationships within logically separate views use listeners. long views share unique identifier (for example, both share model, or @ least identical model ids), can send message reach view i'm interested in.

for you'll need centralized event hub, backbone trivially easy generate. in appropiately global variable (like, example, myapp) do:

myapp.eventbus = _.extend({}, backbone.events); 

set detail view

on detail view initialize function drop listener,

initialize: function () {   // listen toggle visibility on view   this.listento(myapp.eventbus, 'detail-view:toggle-view', toggleview); },  toggleview: function (id) {   if (this.model.id == id) {      // show view if have passed id      this.$el.show()      // notify parent list item view detail view exists      myapp.eventbus.trigger('detail:view:exists', true);   } else {     // hide other views     this.$el.hide();   } },  changename: function () {   // logic parses dom user input    // local variable name    // trigger event 'detail-view:change:name', , send    // parameters our model's id , new name   myapp.eventbus.trigger('detail-view:change:name', this.model.id, name); } 

setting list item view

the list item view want listen name change (or other model property in detail view want list item aware of). we'll set handler 'detail-view:change:name' event.

we'll want wire our click handler toggle visibility of list item's detail view. tricky part handle event view has not been rendered yet (i'm assuming you're lazy loading detail view). set second listener detail:view:exists event detail view triggers when catches detail-view:toggle-view event. if don't hear detail:view:exists event targeted detail view in timely manner (i'm using 100 ms, can play around suit needs), render view.

initialize: function () {   // listen when detail associated list item changes   // the list item name   this.listento(myapp.eventbus, 'detail-view:change:name', onnamechange);   // set property in view if detail view exists   this.listento(myapp.eventbus, 'detail:view:exists',      _.bind(function () { this.detailviewexists = true; }, this));   // create debounced function tests whether view's   // detail view exists   _.debounce(_.bind(this.handleviewstate, this), 100); },  events {   click: 'toggledetailview' },  toggledetailview: function (id) {   myapp.eventbus.trigger('detail-view:toggle-view', this.model.id);   this.handleviewstate(); },  // debounced function wait 100ms asynchronously  // detail view respond. if detailviewexists bit not set true  // assume view not exist , render handleviewstate: function () {   if (!this.detailviewexists)       // view not exist, render , attach view    // set bit false allow testing in event detail view   // destroyed in future   this.detailviewexists = false; },  changename: function (id, newname) {   if (this.model.id == id) {      // change name of list item view      this.$('.item-name').text(newname); } 

the take-away

now, reference between these 2 disparate views shared unique identifier. since, design, these 2 identifiers unique in scope, , should not change, , assuming detail view has been rendered , attached dom, regardless of rendering state list item view able communicate detail view.


Comments

Popular posts from this blog

shopping cart - Page redirect not working PHP -

php - How to modify a menu to show sub-menus -

python - Installing PyDev in eclipse is failed -