I want to start using Backbone.js to better structure my JavaScript files. However, I don't want to redo my application to ouput just JSON via an API. Correct my if I'm wrong, but so far I have the impression that I can still use Backbone.js, even without a JSON API. Now I'm running into a problem where my server returns HTML and the Backbone model doesn't like that and returns an error.
Basically, I want to load an HTML snippet depending on a 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 can use this simple model to retrieve my HTML snippet via Ajax. The request fires correctly, but Backbone returns an error and updateFilter
is never getting called.
Am I not getting something? What do I need to change to make it work with HTML instead of a JSON response? Or shouldn't I use a model at all?
This question is a little bit older, but I found a project on git that describes a really good way of updating your models by looping through the items server side and adding them to the collections when the page is rendered.
https://github.com/runemadsen/Backbone-With-Server-Side-Rendering/blob/master/views/modeltest.erb
I think the answer to this problem is that you need to replace the sync method of your backbone model with one that works with HTML. The below code produces models with the data in the 'snippet' value:
The standard backbone reading functions should just work following this. The writing ones will fail, but you can always extend the function to deal with those.
This isn't really the way that Backbone was designed to operate, but you may be able to shim your content into a model field (call it
snippet
) by including an appropriateparse
function in your model:Again, you're a little outside of Backbone's natural order, here, but you should now be able to use the usual
fetch()
,get()
, andset()
methods to manage the content of the model. For instance,In my opinion the problem is that the accept header of the request contains
application/json
as default which triggers the error. You can tweak the accept header by doingmodel.fetch({ dataType : 'html'})
. The accepted answer to this question: Backbone.js fetch with parameters helped me finding this out.You need to extend your Backbone model to override fetch so that as with the answer from lost you need to pass a datatype to Backbone.Sync