Backbone.js and local storage. You must specify a property or function "url"

I am improving my knowledge of Backbone.js and have this sample code taken from a tutorial. ( http://bardevblog.wordpress.com/2012/01/16/understanding-backbone-js-simple-example/ )

In this example, the server will not have access to the server, so to simulate a search for data from the server, I have a movie.json file name.

What I'm trying to do:

  • Add json data to local storage (using localStorage adapter)
  • To do this, I use Backbone.ajaxSync, which is specified for the Backbone.sync alias using the localStorage adapter: I created the refreshFromServer () method to do this
  • The reason for this is because I am trying to implement a way to retrieve data only once (and only update when I need)

My problems: I have the error " Error while collecting: url property or function must be specified " when refreshFromServer () is called. I do not understand why, because I set the URL collection. (url: "scripts / data / movies.json")

Code example

var Theater = { Models : {}, Collections : {}, Views : {}, Templates : {} } Theater.Models.Movie = Backbone.Model.extend({}) Theater.Collections.Movies = Backbone.Collection.extend({ model : Theater.Models.Movie, localStorage : new Backbone.LocalStorage("MovieStore"), // Unique name within your app. url : "scripts/data/movies.json", refreshFromServer : function() { return Backbone.ajaxSync.apply(this, arguments); }, initialize : function() { console.log("Movies initialize") } }); Theater.Templates.movies = _.template($("#tmplt-Movies").html()) Theater.Views.Movies = Backbone.View.extend({ el : $("#mainContainer"), template : Theater.Templates.movies, initialize : function() { this.collection.bind("reset", this.render, this); }, render : function() { console.log("render") console.log(this.collection.length); } }) Theater.Router = Backbone.Router.extend({ routes : { "" : "defaultRoute" }, defaultRoute : function() { console.log("defaultRoute"); Theater.movies = new Theater.Collections.Movies() new Theater.Views.Movies({ collection : Theater.movies }); Theater.movies.refreshFromServer(); //Theater.movies.fetch(); console.log(Theater.movies.length) } }) var appRouter = new Theater.Router(); Backbone.history.start(); 

Notes:

  • If the localStorage property of the comment in the collection

    Theater.Models.Movie = Backbone.Model.extend ({}) Theater.Collections.Movies = Backbone.Collection.extend ({model: Theater.Models.Movie, // localStorage: new Backbone.LocalStorage ("MovieStore"). ..});

    and then in the normal sample mode of calling the router

    Theater .Router = Backbone.Router.extend ({routes: {":" defaultRoute "},

     defaultRoute : function() { Theater.movies = new Theater.Collections.Movies() new Theater.Views.Movies({ collection : Theater.movies }); //Theater.movies.refreshFromServer(); Theater.movies.fetch(); } 

    })

I see json list correctly in my view

  • If I use the localStorage property in the collection and then call the standard fetch () method, I see only an empty list (I think this is normal, since it is read from the local storage and empty)

  • The error only occurs when using the refreshFromServer () method using Backbone.ajaxSync (an alias for backbone.sync)

+3
source share
1 answer

Err ... my bad. Implement refreshFromServer from my answer to your earlier question. , and this is completely, uselessly wrong.

Backbone.sync expects arguments (method, model, options) , but in its current form it does not get what it needs from refreshFromServer , because the update method simply sends all the arguments it receives. I'm sorry for the mistake.

Correct, working implementation:

 refreshFromServer : function(options) { return Backbone.ajaxSync('read', this, options); } 

It can be used either through success / error callbacks passed to the options hash:

 this.collection.refreshFromServer({ success: function() { /* refreshed... */ }); 

Or through the jqXHR promises API:

 this.collection.refreshFromServer().done(function() { /* refreshed... */ }) 

Or do not register for callbacks and wait for the reset collection event, as in your example:

 this.collection.bind("reset", this.render, this); this.collection.refreshFromServer(); 

That should work. Please let me know if this is not the case. I also corrected my answer in the previous question if someone came across it.

Edit: To save data in local storage after the update, you will need to manually save each of the models:

 var collection = this.collection; collection.refreshFromServer({success: function(freshData) { collection.reset(freshData); collection.each(function(model) { model.save(); }); }}); 
+4
source

All Articles