2012-06-20 20 views
8

Sto mettendo insieme un esempio di backbone in cui i modelli vengono creati modificati e cancellati. Sono in grado di salvare nuovi modelli e modifiche all'archiviazione locale, ma sto riscontrando un problema nel far sì che lo spazio locale venga visualizzato correttamente all'aggiornamento. Sembra che si carichi come un singolo oggetto e quindi mi fornisce un modello indipendentemente da quanti ne sono stati aggiunti.utilizzando localStorage in Backbone.js

var Thing = Backbone.Model.extend({ 
    defaults: { 
     title: 'blank' 
    } 
}); 
var ThingView = Backbone.View.extend({ 
    template: _.template('<b><button id="remove">X</button> <b><button id="edit">Edit</button> <%= title %></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(); 
     this.$el.append(this.template(attributes)); 
     return this; 
    } 
}); 
var ThingsList = Backbone.Collection.extend({ 
    model: Thing, 
    localStorage: new Store("store-name"), 
}); 
var storeVar = localStorage.getItem("store-name"); 
console.log(storeVar); 
var thingsList = new ThingsList; 
thingsList.reset(storeVar); 
var ThingsListView = Backbone.View.extend({ 
    el: $('body'), 
    events: { 
     'click #add': 'insertItem', 
    }, 
    initialize: function() { 
     this.render(); 
     this.collection.on("add", this.renderThing, this); 
    }, 
    insertItem: function (e) { 
     newTitle = $('input').val(); 
     newThing = new Thing({ 
      title: newTitle 
     }); 
     this.collection.add(newThing); 
     newThing.save(); 
     console.log(this.collection.length); 
    }, 
    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); 
    } 
}); 
var thingsListView = new ThingsListView({ 
    collection: thingsList 
}); 

risposta

8
var Thing = Backbone.Model.extend({ 
    defaults: { 
     title: 'blank' 
    } 
}); 
var ThingView = Backbone.View.extend({ 
    template: _.template('<b><button id="remove">X</button> <b><button id="edit">Edit</button> <%= title %></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(); 
     this.$el.append(this.template(attributes)); 
     return this; 
    } 
}); 
var ThingsList = Backbone.Collection.extend({ 
    model: Thing, 
    localStorage: new Store("store-name"), 
}); 
var storeVar = localStorage["store-name-7ee7d1e3-bbb7-b3e4-1fe8-124f76c2b64d"]; 
console.log(storeVar); 
var thingsList = new ThingsList; 
//thingsList.reset(storeVar); 
var ThingsListView = Backbone.View.extend({ 
    el: $('body'), 
    events: { 
     'click #add': 'insertItem', 
    }, 
    initialize: function() { 
    thingsList.fetch(); 
    thingsList.toJSON(); 
     this.render(); 
     this.collection.on("add", this.renderThing, this); 
    }, 
    insertItem: function (e) { 
     newTitle = $('input').val(); 
     newThing = new Thing({ 
      title: newTitle 
     }); 
     this.collection.add(newThing); 
     newThing.save(); 
     console.log(this.collection.length); 
    }, 
    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); 
    } 
}); 
var thingsListView = new ThingsListView({ 
    collection: thingsList 
}); 
+11

usa un piccolo commento su cosa hai fatto esattamente qui. Hai davvero commentato quella frase e tutto è felice ora? Perché ha funzionato? Cosa c'era di sbagliato in primo luogo? –

8

È necessario aggiungere gli elementi alla raccolta e quindi per leggerlo è necessario chiamare fetch. Hai anche un paio di virgole extra trailing nei tuoi oggetti.

Ecco una versione leggermente modificata del codice che sembra funzionare.

var Thing = Backbone.Model.extend({ 
    defaults:{ 
    title:'blank' 
    } 
}); 

var ThingView = Backbone.View.extend({ 
    //el: $('body'), 
    template: _.template('<b><button id="remove">X</button> <b><button id="edit">Edit</button> <%= title %></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(); 
      //remove view from page 
      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(); 
     this.$el.append(this.template(attributes)); 
     return this; 
    } 
}); 

var storeVar = localStorage.getItem("store-name"); 

var ThingsList = Backbone.Collection.extend({ 
    model: Thing, 
    localStorage: new Store("store-name") 
}); 

var things = [ 
    { title: "Macbook Air", price: 799 }, 
    { title: "Macbook Pro", price: 999 }, 
    { title: "The new iPad", price: 399 }, 
    { title: "Magic Mouse", price: 50 }, 
    { title: "Cinema Display", price: 799 } 
]; 

console.log(things); 

var thingsList = new ThingsList; 

var ThingsListView = Backbone.View.extend({ 
    el: $('body'), 

events: { 
     'click #add': 'insertItem' 
    }, 

initialize: function() { 
    this.render(); 
    this.collection.on("add", this.renderThing, this); 
    }, 


    insertItem: function(e){ 
     newTitle = $('input').val(); 
     newThing = new Thing({ title: newTitle }); 
     this.collection.add(newThing); 
     newThing.save(); 
     //this.model.saveItem; 
     console.log(this.collection.length); 
    }, 


    render: function(){ 
    _.each(this.collection.models, function (items) { 
      this.renderThing(items); 
     }, this); 
    }, 


    renderThing: function(items) { 
    //console.log('added something'); 
    var thingView = new ThingView({ model: items }); 
     items.save(); 
    this.$el.append(thingView.render().el); 
    } 

}); 

var thingsListView = new ThingsListView({collection: thingsList}); 
thingsList.fetch(); 
console.log(thingsList.toJSON()); 
thingsList.reset(things); 

Edit: Vedo che sta tentando di leggere il valore memorizzato nella memoria locale sotto "store-name", il modo in cui funziona spina dorsale-localStorage è che utilizza il nome del negozio (nella vostra case "Store-name") per archiviare gli id ​​del resto dei modelli e quindi salva ciascun modello sotto una combinazione del nome del negozio e dell'id, quindi diciamo che avevi tre modelli, avresti finito con 4 voci nella memoria locale ,

localStorage["store-name"] //id1, id2, id3" 
    localStorage["store-name-id1"] //model with id1 
    localStorage["store-name-id2"] // model with id2 
    localStorage["store-name-id3"] // model with id3 

EDIT 2

Ecco un collegamento a un jsfiddle del tuo codice, per iniziare sto lasciando la riga thingsList.fetch(); commentata, togliere commento a tale riga e commentare thingsList.add(things); ed eseguirlo una seconda volta e dovrebbe estrarre i modelli dallo Storage locale (ho lasciato un avviso in là).

+0

Grazie per la risposta Jack. Sfortunatamente questo non sembra funzionare, in quanto nulla da localStorage visualizza sulla pagina. Inoltre mi sono reso conto che ho pubblicato precedentemente una versione precedente dell'app. Ho modificato sopra e sostituito con la versione più recente, che salva in localStorage ma non legge correttamente da esso. – user1469779

+0

Penso che il tuo problema è che stai cercando di leggere i dati direttamente da localStorage in modo errato, ho aggiornato la mia risposta con qualche dettaglio in più. – Jack

+0

grazie Jack, ma questo non funziona ancora. Quando cambio in var storeVar = localStorage.getItem ("store-name-id1"); console.log (storeVar); Restituisce nulla. La mia sintassi è errata? – user1469779