Can't get a views/collection to show? - javascript

I can't seem to get a test backbone.js app working and I have no idea what I am doing wrong.
http://jsbin.com/iwigAtah/1/edit

I modified your code a little bit and here's what I came up with.
// Backbone Objects
var Item = Backbone.Model.extend({});
var List = Backbone.Collection.extend({
model: Item
});
var ListView = Backbone.View.extend({
initialize: function(options){
// collection is now passed in as an argument
// this line isn't necessary but makes it easier to understand what is going on
this.collection = options.collection;
console.log(this.collection.models);
}
});
// Create a new empty collection
var test = new List();
// Create a new item model and add it to the collection
var testItem = new Item();
test.add(testItem);
// Create a view with your new collection
var g = new ListView({
collection: test
});
The main issue you were having is that you weren't actually adding your model to the collection.

Related

New Backbone instance property pointing to old instance property

I noticed something odd with Backbone/Marionette. When I create an instance of a view that has a new collection property, then I create a nother instance of the view, its a new instance but the collection property points to the instance of the first view. See here:
var CollectionView = Marionette.CollectionView.extend({
collection: new Backbone.Collection()
});
var view = new CollectionView();
console.log('view is ', view);
view.collection.searchTerm = 'test';
console.log('view.collection is ', view.collection);
this.region.show(view);
var view2 = new CollectionView();
console.log('view2 is ', view2);
console.log('view2.collection is ', view2.collection);
this.region.show(view2);
You can see in the logs, there are 2 difference view instances (one has cid: "view2" and the other cid: "view5"). But the collection property of the second view has a property searchTerm which is 'test'. I would have expected this to be a new Backbone collection....
Codepen is here.
It is expected behavior.
Collection is created only once, when you're calling extend. All instances just have collection reference in prototype of CollectionView.
If you want your view instantiated with new collection every time, just create initialize method:
var CollectionView = Marionette.CollectionView.extend({
initialize: function () {
this.collection = new Backbone.Collection();
}
});
var view = new CollectionView();
console.log('view is ', view);
view.collection.searchTerm = 'test';
console.log('view.collection is ', view.collection);
this.region.show(view);
var view2 = new CollectionView();
console.log('view2 is ', view2);
console.log('view2.collection is ', view2.collection);
this.region.show(view2);

Backbone.Collection get first n as new collection

I have a Backbone.Collection which has been set up like so:
let col = new Backbone.Collection();
let model1 = new Backbone.Model();
model1.set('name', 'first');
col.add(model1);
let model2 = new Backbone.Model();
model2.set('name', 'second');
col.add(model2);
let model3 = new Backbone.Model();
model3.set('name', 'third');
col.add(model3);
When I attempt to select the first 2 models from the collection with this:
let firstTwo = col.first(2);
firstTwo contains model1 and model2 as an array.
How can I get the first two as a Backbone.Collection without manually adding them all to a new collection?
You have to create a new Collection & add them. The good news is creating a new collection is very inexpensive, and the model instances will be the same ones in both the full and partial collection.
Collections automatically have some Underscore methods built into them. But these method all return arrays of Model objects. If you want to instead get a Collection instance, your best bet is to create another method on your Collection class. You can still use the Underscore methods to do the filtering, however.
var MyCollection = Backbone.Collection.extend({
// ...
firstAsCollection: function(numItems) {
var models = this.first(numItems);
return new MyCollection(models);
}
});
You could create a function inside your col model that should behave something like the following:
sublist: function (numberOfElements) {
var i = 0;
return this.filter(function (model) {
if (i <= numberOfElements){
return true;
}
return false;
});
}

How can we create an instance of Backbone view using the string name store in a javascript object?

I'm creating a visual builder using different view for each component. All the view are declared like below:
$(function() {
var parallaxView = new Backbone.view.extend({
....
});
var parallaxView = new Backbone.view.extend({
....
});
});
At one point i start to create a new object view from that view. But all i know is the string represent the name of the view store in an object
name
My question can we create an object in some way such as new class using that object value as class name.
var myView = new name(param1, param2);
instead of using
switch (name) {
case 1:
....
}
I have try this case
var myView = new name(param1, param2);
and i know that it won't wok. But is there any way to can create an object in someway like that?
If I understand your question in a right way, you can store views constructors in object like this:
$(function() {
window.views = {
'parallax': Backbone.View.extend({ /*...*/ }),
'test': Backbone.View.extend({ /*...*/ })
};
});
Then you can create instances this way:
// var name = 'parallax';
var myView = new window.views[name](param1, param2);
Please let me know if your problem is not like I understand it.

Setting Backbone attributes in a model in a nested collection

Pretty new to Backbone JS and I need to know the 'right' way of looping through and setting attributes on models in a collection that is within a model.
My models look like this:
var mediaItem = Backbone.Model.extend({
});
var mediaItems = Backbone.Collection.extend({
model: mediaItem
});
var story = Backbone.Model.extend({
initialize: function () {
this.MediaItems = new mediaItems(this.get('MediaItems'));
this.MediaItems.parent = this;
}
});
What I want to do is loop through the MediaItems in a given story and set the width and height of each. If I do it like this...
storyInstance.MediaItems.each(function (mediaItem) {
mediaItem.set('Width', 200);
mediaItem.set('Height', 100);
});
...then the MediaItem models within the storyInstance.MediaItems property are correctly updated, but the objects within storyInstance.attributes.MediaItems are not. And it's the attributes tree that appears to be used when I subsequently call toJSON() on the Story model.
I can probably amend the above to loop through attributes instead, but I get the feeling I've set up the models wrong or there's a more standard way of doing this?
Thanks.
Probably initialize something other than what you expected.
The below code
var story = Backbone.Model.extend({
initialize: function () {
this.MediaItems = new mediaItems(this.get('MediaItems'));
this.MediaItems.parent = this;
}
});
should have been
var story = Backbone.Model.extend({
initialize: function () {
this.MediaItems = this.get('MediaItems');
this.MediaItems.parent = this;
}
});
and instantiating items should be done with instantiation of story model like
var storyInstance = new story({
MediaItems: new mediaItems()
})
then
story.MediaItems.each(function (mediaItem) {
mediaItem.set('Width', 200);
mediaItem.set('Height', 100);
});
would result updating both
Edit: Did not realize this was from '13. It showed up in questions tagged backbone.js and I did not notice the date/time till now.
Try to check for the instance of Array in the initialize section.
var story = Backbone.Model.extend({
initialize: function () {
if(this.get('MediaItems') instanceof Array){
this.MediaItems = new mediaItems(this.get('MediaItems'));
}
else {
this.MediaItems = this.get('MediaItems');
}
this.MediaItems.parent = this;
}
});

How to get a filtered collection

Lets suppose I have a big collection and I want to use a subset of this big collection for different view.
I tried the following code but it does not work because the filtered collection actually is a new one and it does not refer to the BigCollection instance.
My question is:
how can I get a collection which is a subset of BigCollection instance?
Here is my code. Please see the comments for more info:
// bigCollection.js
var BigCollection = Backbone.Collection.extend({
storageName: 'myCollectionStorage',
// some code
});
// firstView.js
var firstView = Marionette.CompositeView.extend({
initialize: function(){
var filtered = bigCollection.where({type: 'todo'});
this.collection = new Backbone.Collection(filtered);
// the issue is about the fact
// this.collection does not refer to bigCollection
// but it is a new one so when I save the data
// it does not save on localStorage.myCollectionStorage
}
});
Use BigCollection to make filtered collection, like this :
// firstView.js
var firstView = Marionette.CompositeView.extend({
initialize: function(){
var filtered = bigCollection.where({type: 'todo'});
this.collection = new BigCollection(filtered);
// now, it will save on localStorage.myCollectionStorage
}
});
You could just save your original models in a variable inside your collection so you can restore them after you de-apply the filter, like this:
// bigCollection.js
var BigCollection = Backbone.Collection.extend({
storageName: 'myCollectionStorage',
// some code
});
// firstView.js
var firstView = Marionette.CompositeView.extend({
initialize: function(){
bigCollection.original_models = bigCollection.models;
bigCollection.models = bigCollection.where({type: 'todo'});
}
});
And then you can restore them when you toggle the filter:
bigCollection.models = bigCollection.original_models;

Categories

Resources