One thing I was trying to figure out lately is if it was possible to filter a collection from an array of id’s. Imagine you got a task model that lists another sub-task model. In your task model you got an array of sub-tasks, [1,4,7]. How would you go to retrieve those models?
The loop
The easiest way of doing this is by looping the array and saving the models one by one in a new collection.The code in your view would look like something like this:
var currentSubtask = new SubtaskCollection; _.each(this.model.toJSON().subtasksArray, function(taskID){ var mySubTask = allSubTasks.getOne(taskID) currentSubtask.add(mySubTask) })
When we are about to show the sub-tasks for a master task, we loop our sub-tasks array and retrieve the sub-tasks one by one.
In our sub-tasks collection declaration, we would have this filter:
getOne : function(SubTaskid){ return this.filter(function(data) { return data.get("id") == SubTaskid; }); },
Easy, we get one model each time. Obviously this technique is really not the most efficient. What we really want to achieve is not having to loop through our sub-tasks array on the view side, but directly pitch the array in the collection filter.
A better way
To do this we will have to change our filter, what we will do is check if each model through our collection exists in our sub-tasks array. If its not, its going to return -1 and in that case we are not going to keep it.
getGuestById : function(subtasksArray){ return this.select(function(model){ return (_.indexOf(subtasksArray, model.get("id")) > -1); }); }
This will return a list of models that you can add to a collection. We could also return a collection of those models directly wrapping everything with _()
getGuestById : function(subtasksArray){ return _(this.select(function(model){ return (_.indexOf(subtasksArray, model.get("id")) > -1); })); }
That’s it
Here we go for filtering with arrays, in my next article I will use this technique to “bind” 2 models together and handle small relationships.