1

Ich habe ein Modell A und eine Sammlung von As wie folgt erweitert:Backbone: Synchronisieren von Models und Localstorage

define(['underscore', 'backbone', 'backbone.localStorage'], function(_, Backbone) { 
    var A = Backbone.Model.extend({ 
     initialize: function() {   
     } 
    }); 

    var A_Collection = Backbone.Collection.extend({ 
     model: A, 
     localStorage: new Backbone.LocalStorage("as") 
    }); 

    return { 
     Model: A, 
     Collection: A_Collection 
    }; 
}); 

Kollektionen in localstorage gespeichert werden und alle Arbeiten in meiner Anwendung in Ordnung. Dann ersetze ich klar und die localstorage direkt von Code (mit klaren und setItem Funktionen) und versuchen, eine neue Kollektion zu instanziieren, aber die Änderungen werden nicht erkannt:

var aux = new A.Collection(); 
aux.fetch(); 
// aux is empty 

Andernfalls, wenn ein Versuch:

var aux = new A.Collection(); 
aux.localStorage = new Backbone.LocalStorage("as"); 
aux.fetch(); 
// aux contains new data 

Letzteres gilt nicht für mich, da ich die Erstellung von Sammlungen in meinem Projekt ändern müsste.

Was fehlt mir?

Antwort

1

Instanzen von Backbone.LocalStorage sind nicht darauf ausgelegt, auf LocalStorage Änderungen zu achten, die außerhalb ihres eigenen Codes auftreten. Deshalb bekommst du das Verhalten, das du bekommst. Es gibt jedoch eine Problemumgehung.

Wenn Sie definieren eine Sammlung wie folgt aus:

var A_Collection = Backbone.Collection.extend({ 
    model: A, 
    localStorage: new Backbone.LocalStorage("as") 
}); 

der localStorage Wert wird geteilt durch alle Instanzen von A_Collection. Sie können automatisch eine neue Instanz von Backbone.LocalStorage, wie diese erstellen:

var A_Collection = Backbone.Collection.extend({ 
    model: A, 
    initialize: function() { 
    A_Collection.__super__.initialize.apply(this, arguments); 
    A_Collection.prototype.localStorage = new Backbone.LocalStorage("as"); 
    }, 
}); 

Wir haben es auf dem Prototyp zu setzen, so dass sie von allen Instanz A_Collection geteilt wird, die das gleiche Verhalten wie das Original-Code ist. Wenn Sie eine neue Instanz von A_Collection erstellen, erhalten Sie eine neue Instanz von Backbone.LocalStorage, die Informationen von LocalStorage erhalten wird.

Hier ist ein plunker zur Veranschaulichung. Hier ist der relevante Code als Referenz:

var A = Backbone.Model.extend({ 
    initialize: function() {} 
}); 

var A_Collection = Backbone.Collection.extend({ 
    model: A, 
    initialize: function() { 
    A_Collection.__super__.initialize.apply(this, arguments); 
    A_Collection.prototype.localStorage = new Backbone.LocalStorage("as"); 
    }, 
}); 

// Setup a collection. 
var collection = new A_Collection(); 
collection.fetch(); 

// Clean it out from previous runs... Note that we have to use destroy to destroy all items. 
// Reset won't save to LocalStorage. 
while (collection.length > 0) { 
    var model = collection.at(0); 
    model.destroy(); 
    collection.remove(model); 
} 
// and set some elements. 
collection.create({ 
    name: "1" 
}); 
collection.create({ 
    name: "2" 
}); 
console.log("collection length:", collection.length); 

// Mess with it outside the Backbone code. 
localStorage.clear(); 
// Manually create data that looks like what Backbone expects. 
localStorage.setItem("as-1", JSON.stringify({ 
    name: "foo", 
    id: "1" 
})); 
localStorage.setItem("as-2", JSON.stringify({ 
    name: "bar", 
    id: "2" 
})); 
localStorage.setItem("as-3", JSON.stringify({ 
    name: "baz", 
    id: "3" 
})); 
localStorage.setItem("as", "1,2,3"); 

// Create a new collection that loads from LocalStorage 
var collection2 = new A_Collection(); 
collection2.fetch(); 
console.log("collection 2 length:", collection2.length); 
console.log("first item", collection2.at(0).toJSON()); 
console.log("third item", collection2.at(2).toJSON()); 

console.log("instance is shared?", collection.localStorage === collection2.localStorage); 

Der obige Code erzeugt dies auf der Konsole:

collection length: 2 
collection 2 length: 3 
first item Object {name: "foo", id: "1"} 
third item Object {name: "baz", id: "3"} 
instance is shared? true 
+0

Wow, wirklich beeindruckt. Das habe ich gesucht. Vielen Dank – acimutal