I am trying to understand how Backbone.LocalStorage is used the from the following jagin/todos.
Referring to the Backbone.Marionette doc, In order to render the list of todos, it should be enough to make the following code:
new CompositeView({
model: someModel,
collection: someCollection,
itemView: RowView
});
So, referring to the jagin/todos the collection should be an object fetched from the backbone.localstorage.
My question is:
I would like to get this collection/models from the javascript console.
I did try the following but it returns an object which is different from a backbone.collection.
new Backbone.LocalStorage("todos-marionette");
// {"name":"todos-marionette","records":["1244f588-be3d-c493-5c86-b2abb997af82"]}
Any ideas?
Related
I have a very simple Backbone example:
var myModel = Backbone.Model.extend();
var collection = Backbone.Collection.extend({
model: myModel,
});
var c = new collection([
{first_name: 'a',
last_name:'b'
},
{first_name:'c',
last_name:'d'
}
]);
console.log('c is');
console.log(c);
You can see jsfiddle here.
When you view this in Chrome developer tools, you can see there is a collection attribute on each Backbone model, which you can expand and go into again, infintely. See the image:
What is this? Why does it appear like that?
Inside every model there is a collection object stored if it is part of a collection. What is happening here is you are viewing collection in console and inside it there are two models. Each model has collection object stored in it (which is the same collection which you are viewing). So, it seems like sort of recursion when viewing in console
This is currently not documented in backbone js. See https://github.com/jashkenas/backbone/issues/1161 for more info.
I am studying Backbone.js through the example todomvc application from here:
http://todomvc.com/architecture-examples/backbone/
And I'm sort of stuck in the app-view.js part here:
https://github.com/tastejs/todomvc/blob/gh-pages/architecture-examples/backbone/js/views/app-view.js
Here's the snippet of the code:
// Add a single todo item to the list by creating a view for it, and
// appending its element to the `<ul>`.
addOne: function (todo) {
var view = new app.TodoView({ model: todo });
this.$list.append(view.render().el);
},
Where did the 'todo' variable comes from on the function 'addOne'?
I searched the whole project files and so far didn't find any specific function that specifies or initialize the 'todo' variable.
I tried to read the Backbone.js and Underscore.js docs on their website and so far haven't find the explanation.
Ok to make what #Evgeniy said more readable..
When you listen to 'add' on a collection the first thing that is passed to the listening method is the added model:
this.listenTo(app.todos, 'add', this.addOne);
Here is the line in the backbone source:
(model = toAdd[i]).trigger('add', model, this, options);
So you can see the first param is the added model, then the collection, then any options passed through from this.collection.add(model, [options]).
addAll is also calling addOne - it loops over all the models and adds views for them one-by-one:
app.todos.each(this.addOne, this);
In each case the first param is going to be a model which needs a view added for it.
In backbone javascript models, we get individual items as shown below:
var type = this.model.get("type");
Here, type will be defined in server side & then fetched in JS using above syntax.
My question is how do I get the entire model in one shot?
I tried this.model.toString() but it prints [object object]
Any suggestion?
EDIT: I'm using above line of code in backbone view & not the model. And in this view, I need to read all the models data even if its JSON string, thts fine with me. How do I get it. I don't want to use separate collection or anything else. I need to update the above view only to get entire model.
You can use model.toJSON() to get all the attributes of a model.
you use a collection
http://backbonejs.org/#Collection
You can then iterate though the collection to obtain each model.
var Library = Backbone.Collection.extend({
model: Book
});
for example and then
books = new Library();
books.each(function(book) {
book.publish();
});
to iterate
I am using backbone local storage and experiencing some weird behavior.
I have a Model and Collection that is defined, instantiated, and fetched:
MyModel = Backbone.Model.extend({
localStorage: new LocalStore('example-myModels')
//note: LocalStore = Backbone.LocalStore -> https://github.com/jeromegn/Backbone.localStorage
});
MyCollection = Backbone.Collection.extend({
model : MyModel,
localStorage: new LocalStore('example-myModels')
});
var myCollection = new MyCollection();
myCollection.fetch(...);
This collection is then displayed as a list to the user. The user is able to "add" an item to the collection which eventually results in this code:
var newModel = new MyModel();
newModel.save(newModelAttributes, {
success: function(newlySavedModel) {
myCollection.add(newlySavedModel);
}
);
At this point myCollection has the newly added model and I can see the record successfully created in my localStorage database:
Pre-save LocalStorage:
Post-save LocalStorage:
The next step after the user adds the record is to go back to the list, at which point the collection is fetched again:
myCollection.fetch();
Now myCollection no longer contains the new record. No matter how many times I fetch, the new record will not be retrieved - even though I can see it in my localStorage database. I have also tried creating a new instance of the Collection and fetching that but it yields the same results. If I reload the browser, the new record appears as expected. Anyone have any idea what is going on? I get the feeling I am missing something fundamental here...
A running example that reproduces the issue is available here: http://jsbin.com/iyorax/2/edit (make sure the console is visible and click "Run with JS")
Thanks in advance!
Your model and your collection need to share a reference to the same instance of LocalStore, whereas right now you are creating two different objects. To fix this, create the LocalStore object outside of either model or collection, and pass in a reference to it in the constructors of your Model and collection.
I have an application working with Backbone.localstorage and what works for me is I first add the model to the collection and then I call save to the model. like this.
var newModel = new MyModel();
myCollection.add(newModel)
newModel.save();
Im not 100% sure, but my reasoning is that, your model is saved, but your collection is not, and perhaps an index is not being updated and at the time that you call fetch you are getting the unupdated collection.
Hope that helps.
The only reason I can think of due to which the model is not present in the collection is because of Duplicated ID's
I don't see a IdAttribute defined on the model. That could be a problem sometimes.
I have a table that I am populating when new items are added to a collection and I am populated a deleted items collection when Items are deleted from that collection.
Then I have a single save button, that triggers the save/delete events on the collections.
Saves are working just fine but only half of my deletes are working and I am confused.
class MyApp.Collections.DeletedTasks extends Backbone.Collection
model: MyApp.Models.Task
destroy: () ->
console.log('destroy the collection size: ' + #.models.length)
_.each(#.models, #sendDelete)
sendDelete: (model) ->
console.log('deleting model with id: ' + model.get('id'))
model.destroy()
Console output
Done with Adding/Updating Collections
destroy the collection size: 6
deleting model with id: KSc18d06fefddbebd2ade74bcab4c670c907
deleting model with id: KS07cb95935b1caf3817758739224a3e1a2f
deleting model with id: KS6f473b3e15740fe7c6c0909e14986700a9
What happened?
Why did it only do 3?
How do I debug this?
Any help is appreciated!
Tim already gave a fine answer, but there's a better way:
Underscore's iteration methods are already a part of Backbone collections, which means that instead of
_.each(#.models, #sendDelete)
you can simply write
#each(#sendDelete)
That also takes care of converting #models to an array for you, preventing destroy() from messing up the iteration.
You should never have to use #models directly; it should be thought of as an internal property, like #attributes on models.
copy the collection to an array first. You're removing from a collection that is being enumerated. I'm not a coffee script guru but something like:
_.each(#.models.toArray(), #sendDelete)