Backbone model with server side HTML rendering

I want to start using Backbone.js to better structure my JavaScript files. However, I do not want to repeat my application in order to release JSON through the API. Correct mine if I'm wrong, but so far I have the impression that I can still use Backbone.js, even without the JSON API. Now I am faced with a problem when my server returns HTML, but the Backbone model is not like and returns an error.

Basically, I want to load an HTML snippet depending on the category:

var Filter = Backbone.Model.extend({ url: '/filters/', }); var FilterView = Backbone.View.extend({ initialize: function() { this.model.on('change', this.updateFilter, this); this.changeFilter(); }, changeFilter: function() { this.model.fetch({data: $.param({category: this.options.category})}); }, updateFilter: function(filters) { console.log(filters); this.$el.html(filters); }, }); var filter = new Filter(); var filterView = new FilterView({ el: $( '#filterContainer' ), category: $( '#categorySlug' ).data( 'slug' ), model: filter, }); 

Now I thought that I could use this simple model to extract my HTML fragment through Ajax. The request works correctly, but Backbone returns an error and updateFilter will never be called.

Am I really not getting something? What do I need to change so that it works with HTML instead of a JSON response? Or should I not use the model at all?

+2
source share
5 answers

You need to expand the Backbone model to override the selection, so as with the answer > lose , you need to pass the data type to Backbone.Sync

 fetch: function(options) { return Backbone.Model.prototype.fetch.call(this, _.extend({ dataType: "html"}, options)); } 
+3
source

Actually, this is not the way Backbone was designed to work, but you can strengthen your content in the model field (name it snippet ) by including the appropriate parse in your model:

 var Filter = Backbone.Model.extend({ url: '/filters/', parse: function (response) { return { snippet: $(response) } } }); 

Again, you are a little outside the natural order of Backbone, here, but now you can use the usual fetch() , get() and set() methods to manipulate the contents of the model. For example,

 // in view: updateFilter: function (filter) { this.$el.html(filter.get('snippet')); }, // etc.. 
+2
source

In my opinion, the problem is that the accept header of the request contains the default application/json , which causes an error. You can customize the acceptance header by executing model.fetch({ dataType : 'html'}) . The accepted answer to this question is: Backbone.js fetch with parameters helped me find this.

+2
source

I think the answer to this problem is that you need to replace the synchronization method of your base model with the one that works with HTML. The code below shows models with data set to "snippet":

 sync: function (method, model, options) { // NOTE: This generic function won't work for pushing changes if (method !== 'read') { console.log('Cannot update html model'); return false; } // As we're only reading default type to GET - see Backbone.sync // for a more generic way of doing this. var params = _.extend({ type: 'GET', contentType: 'application/xml', dataType: 'text' }); var urlError = function () { throw new Error('A "url" property or function must be specified'); }; // ensure that we have a URL if (!params.url) { params.url = _.result(model, 'url') || urlError(); } // NOTE: If you extend this function to deal with creates you'll need to ensure // params.data is set and make sure that the data isn't processed. // See the Backbone.sync methods for more info // Finally wrap the backbone success callback to plonk the data in snippet field of an object var origSuccess = options.success; options.success = function (data, textStatus, xhr) { origSuccess({ snippet: data }, textStatus, xhr); }; // Make the request, allowing the user to override any Ajax options. var xhr = options.xhr = Backbone.ajax(_.extend(params, options)); model.trigger('request', model, xhr, options); // make the request return xhr; } 

Standard skeleton reading functions should only work after that. Written errors will fail, but you can always expand the function to deal with them.

0
source

This question is a bit older, but I found a project on git that describes a really good way to update your models by going through the server side of the elements and adding them to collections when rendering the page.

https://github.com/runemadsen/Backbone-With-Server-Side-Rendering/blob/master/views/modeltest.erb

0
source

All Articles