In my Backbone App i'm trying to merge collections by using the _.union-method from Lodash (Underscore).
So I have the following:
var myCollection = _.union([carsCollection], [motorcycleCollection], [bikeCollection]);
when I do console.log(collection) it gives me [child, child, child] where each child contains an array of the Models from the collection and its attributes. So far so good, my question is now:
How can I display this in a View? I tried:
this.insertView(new View({collection: myCollection }));
but that didnt work...
Does anyone know whta the issue is here?
Backbone collections are not arrays of models, using _.union on them won't produce a collection of models. You have to work with the collection.models and then build a new collection :
var models = _.union(
carsCollection.models,
motorcycleCollection.models,
bikeCollection.models
);
var unitedCollection = new Backbone.Collection(models);
See http://jsfiddle.net/nikoshr/uc5cn/ for a demo
Related
Background
I have an angular-meteor app and a collection of business objects in mongodb, e.g.:
{ startDate: new Date(2015, 1, 1), duration: 65, value: 36 }
I want to render this data in different views. One of the views is a graph, another is a list of entries.
The list of entries is easy. Just bind the collection to the model:
vm.entries = $scope.meteorCollection(MyData, false);
In the view I would do:
<div ng-repeat="entry in vm.entries">{{entry.startDate}} - ...</div>
But now for the graph. I want to transform each element into a { x, y } object and give the view that, e.g.:
vm.graphPoints = transformData(getDataHere());
The problem is that the data is not fetched here, in angular-meteor is looks like it is fetched when calling the entry in vm.entries in the view. The kicker is that the transformData method, needs to loop through the data and for each item index into other items to calculate the resulting x, y. Hence I cannot use a simple forEach loop (without having access to the other items in some way).
Question
So how can i fetch the data in the controller - transform it - and still have one-way binding (observing) on new data added to the database?
Thanks
Update
The following code works, but I think there could be performance problems with fetching the whole collection each time there is a change.
$scope.$meteorSubscribe("myData").then(function() {
$scope.$meteorAutorun(function() {
var rawData = MyData.find().fetch();
vm.model.myData = transformData(rawData);
});
});
EDIT:
This is the current solution:
$scope.collectionData = $scope.meteorCollection(MyData, false);
$meteor.autorun($scope, function() {
vm.graphPoints = transformData($scope.collectionData.fetch());
});
There is some missing information. do you wan't to have some kind of model object in the client? if that is correct I think you have to do something like this:
$meteor.autorun($scope, function() {
vm.graphPoints = transformData($scope.meteorCollection(MyData, false));
});
How about using the Collection Helper Meteor package to add the function:
https://github.com/dburles/meteor-collection-helpers/
?
Hi I am using Backbonejs, I have a example collection
var MyCollection=Backbone.Collection.extend({
init:function(options){xxx},
getPageNumber:function(){this.length/100},
myfilter:function(){},
});
The problem is I want to add this myfilter function, that filter out the collection, and return the same type "myCollection", so that I can then call getPageNumber(). like this:
collection.myfilter(cb).getPageNumber();
The default filter function in backbone return a simple array, not the Backbone.Collection Object. so is the underscorejs.filter.(which essensially is the same as Backbone.collection.filter). I am wondering if there is an easy way to do it.
Thanks
you can refresh your original collection using reset
myfilter:function(){
var result = yourFilterLogicHere...
this.reset(result);
return this;
}
How to get support for dot notation/nested objects in backbone model. The plugins that are available are buggy and wondering if backbone would ever support
person = { name : {first: 'hon',last:'son'}}
model = new Backbone.Model(person)
model.get('name.first')
model.set('name.first','bon')
There are two plugins to get the job done:
Backbone Nested
Backbone Deep Model
Both handle getting and setting attributes and change events for dot notation.
I did that if i were you:
var nameObj = model.get('name')
nameObj.first = bon
model.set('name', nameObj)
I have this code in my Backbone application:
app.Collections.quotes = new app.Collections.Quotes();
app.Collections.quotes.fetch();
And I can see an array of Objects returned in the network tab but when I expand out the Collection, the Models array inside is 0. Do they get instantiated as Models when fetch() is ran on a new Collection?
This is my Collection:
app.Collections.Quotes = Backbone.Collection.extend({
model: app.Models.Quote,
url: function() {
return app.Settings.apiUrl() + '/quotes';
}
});
EDIT:
app.Collections.quotes.fetch({
success: function(){
app.Utils.ViewManager.swap('section', new app.Views.section({section: 'quotes'}));
}
});
And in my Model:
idAttribute: 'Number',
This was the fix! Thanks for help. Dan kinda pointed me in the right direction amongst the comments...
Calling fetch() on a Collection attempts to populate the JSON response into Models: Collection#fetch.
Is your server definitely returning a valid JSON array of objects?
Do you have any validation on your Quote Model? I'm pretty sure Backbone validates each models before populating the collection, only populating with the models which pass. So if it exists, check that your Model#validate method is working correctly.
You shouldn't need an ID (although it's obviously required if you want to edit them).
I'm making a Grocery list app, which is very similar with the todo list. I have several years of Rails dev experience, but am having trouble figuring out from all the examples what to put into a collection, and what to make a model.
I mocked up the app with Sinatra and Redis as the backend. My goal is to make Sinatra just the simple API and have backbone manage all the view.
Right now, a Grocery list is just a complex ID, which has a Set of string items. So something like:
/lists/asdfasdf34asdf => ["eggs", "bacon", "milk"]
Moving to backbone, would I make the model an "Item" and then the collection would be the "List", or would it be something else?
I guess my routes aren't classic Rest so maybe that's why i'm having trouble sorting out what to do where.
If there's only one grocery list, a Collection of item Models is probably appropriate. Backbone isn't too prescriptive about how things are organized, but you will definitely want to set the url property of each model/collection in a logical fashion. You might do something like this:
var app = {
item: Backbone.Model.extend({
// define an item model to go in the itemCollection
}),
itemCollection: Backbone.Collection.extend({
initialize: function (key) {
this.key = key;
},
model: app.item,
url: function () {
return 'lists/' + this.key + '/items/'
}
})
}
and then instantiate each version of the application along these lines:
var userListKey = 'foobar',
userCollection = new app.itemCollection(foobar);
// proceed with app. Requests for userCollection will now be
// directed to /lists/foobar/items
There are many other ways to do this, but hopefully this is a start.