sorting - Trigger sort method from an event in Backbone.js -
i have backbone.js project uses comparator function defined in collection. sorts items when page refreshed, trying sort when button clicked instead of on page refresh. here code:
var thing = backbone.model.extend({ defaults: { title: 'blank', rank: '' } }); var thingview = backbone.view.extend({ classname: 'thingclass', template: _.template('<b><button id="remove">x</button> <b><button id="edit">edit</button> <%= title %> rank:<%= rank %></b>'), edittemplate: _.template('<input class="name" value="<%= name %>" /><button id="save">save</button>'), events: { "click #remove": "deleteitem", "click #edit": "edititem", "click #save": "saveitem", }, deleteitem: function () { console.log('deleted'); this.model.destroy(); this.remove(); }, edititem: function () { console.log('editing'); this.$el.html(this.edittemplate(this.model.tojson())); }, saveitem: function () { console.log('saved'); edittitle = $('input.name').val(); console.log(edittitle); this.model.save({ title: edittitle }); this.$el.html(this.template(this.model.tojson())); }, render: function () { var attributes = this.model.tojson(); //console.log (attributes); this.$el.append(this.template(attributes)); return this; } }); var thingslist = backbone.collection.extend({ model: thing, localstorage: new store("store-name"), comparator: function(thing) { return thing.get('rank'); }, }); var thingslist = new thingslist; var thingslistview = backbone.view.extend({ el: $('body'), events: { 'click #add': 'insertitem', 'click #sort': 'sortitems', }, initialize: function () { thingslist.fetch(); thingslist.tojson(); this.render(); this.collection.on("add", this.renderthing, this); this.collection.on("reset", this.clearrender, this); }, insertitem: function (e) { newtitle = $('#new-item').val(); newrank = $('#rank').val(); newthing = new thing({ title: newtitle, rank: newrank }); this.collection.add(newthing); newthing.save(); console.log(this.collection.length); }, sortitems: function (e) { console.log('clicked sort button'); this.collection.sort(); this.$el.detach('.item'); }, render: function () { _.each(this.collection.models, function (items) { this.renderthing(items); }, this); }, renderthing: function (items) { var thingview = new thingview({ model: items }); this.$el.append(thingview.render().el); }, clearrender: function () { console.log('clear render called') _.each(this.collection.models, function (items) { //this.remove(); this.$el.remove(".thingclass") this.renderthing(items); }, this); }, test: function (items) { console.log('test worked'); }, }); var thingslistview = new thingslistview({ collection: thingslist });
are sure collection isn't resorting itself? keep in mind order of models in collection won't change order of how appear on page if rendered.
i'm guessing trying resort items have been rendered, need re-render collection. if going recommend cache views , on sort detach associated element dom , reattach them in correct order.
as example
var thingslistview = backbone.view.extend({ _views: {}, initialize: function () { this.collection.bind('add', this.add, this); this.collection.bind('reset', this.render, this); //sort triggers reset }, add: function (thing) { var view = new thingview({model: thing}); this._views[thing.cid] = view; //use client id of model key views cache this.$el.append(view.render().el); }, render: function() { $('li, this.$el).detach(); //detach bound events aren't lost _.each(this.collection.models, function(thing) { this.$el.append(this.views[thing.cid].el); //get view cache },this); }, sort: function() { this.collection.sort(); } } })
(a couple of differences example code , yours i'm assuming here collection view has 'el' referring container 'ul', don't show how triggering sort (basically thinglistview.sort()
;)
edit: might not obvious example code posted, should have mentioned begin @deeptechtons said when sort collection triggers reset
event
edit2: if not interested in caching views, easiest way remove current views probablly add class rendered div
var thingview = backbone.view.extend({ classname: 'thingclass', //rest of thingviewcode
then in clearrender method add $(".thingclass", this.$el).remove();
beginning of method.
Comments
Post a Comment