Backbone.js y almacenamiento local. Debe especificarse una propiedad o función “url”

Estoy mejorando mi conocimiento sobre Backbone.js y obtengo este ejemplo de código de un tutorial. ( http://bardevblog.wordpress.com/2012/01/16/understanding-backbone-js-simple-example/ )

Este ejemplo no accederá al servidor por ahora, así que para simular la recuperación de datos del servidor tengo un nombre de archivo movies.json.

Lo que estoy tratando de hacer:

  • Agregue datos json en el almacenamiento local (usando el adaptador localStorage)
  • Para esto estoy usando Backbone.ajaxSync, que se le da al alias Backbone.sync por el adaptador localStorage: creé el método refreshFromServer () para hacer esto
  • La razón para hacer esto es que estoy tratando de implementar una forma de obtener datos solo una vez (y solo actualizar cuando sea necesario)

Mis problemas: Tengo un error ” Error no detectado: se debe especificar la propiedad o función ‘url’ ” cuando llamo refreshFromServer (). No entiendo por qué, porque configuro la colección de url. (url: “scripts / data / movies.json”)

Código de muestra

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(); 

Notas:

  • Si una propiedad localStorage comentario en la colección

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

    y luego en el enrutador llamar método normal de recuperación

    Theater.Router = Backbone.Router.extend ({rutas: {“”: “defaultRoute”},

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

    })

Puedo ver la lista de json correctamente en mi vista

  • Si uso la propiedad localStorage en la colección y luego llamo al método fetch () estándar, solo veo una lista vacía (creo que es normal, ya que se lee desde el almacenamiento local y está vacía)

  • El error solo se produce cuando se utiliza el método refreshFromServer () que utiliza Backbone.ajaxSync (alias para backbone.sync)

Err … mi mal. La implementación refreshFromServer es de mi respuesta a su pregunta anterior. , y es completamente, inútilmente mal.

Backbone.sync espera argumentos (method, model, options) , pero tal como está, no obtiene lo que necesita de refreshFromServer porque el método de actualización simplemente envía los arguments que recibe. Lo siento por el error.

La implementación correcta y operativa sería:

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

Se puede usar a través de devoluciones de llamada de success / error pasadas al hash de options :

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

O a través de la API jqXHR Promise:

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

O no registrarse para recibir devoluciones de llamada y esperar el evento de reset recostackción, como en su ejemplo:

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

Esto debería funcionar. Por favor, hágamelo saber si no es así. También arreglé mi respuesta en la pregunta anterior, en caso de que alguien tropiece con ella.

Editar: para guardar los datos en el almacenamiento local después de actualizar, debe save manualmente cada uno de los modelos:

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