1

I am currently creating a page using Knockback.js that displays an employee's tasks in a table. I have a view model for a task, which contains a boolean observable called isSelected. The view model for an employee contains a collection observable of a collection of task view models called 'tasks'.

I now want to add an attribute/function/observable called 'selectedTasks' which only exposes the selected tasks. I want to meet the following requirements:

  • Both the 'tasks' and 'selectedTasks' should give me view models, not models.
  • When I add a model to the original tasks collection, the 'tasks' observable should get updated.
    • When the user selects this newly added model, the 'selectedTasks' should get updated as well.
  • There should be only one view model for every task model. Otherwise I might get a view model that states task x is not selected while another view model states that x is selected.

To demonstrate it a bit more clearly, I created this jsfiddle: http://jsfiddle.net/drojoke/cg6d88Lp/14/

So far, I only managed to get everything working for the 'tasks' attribute using a collection observable, as seen here:

this.tasks = kb.collectionObservable(tasks, {
    view_model: function (task) {
        return new TaskViewModel(task);
    }
});

I'm using the view_model option to turn every task in the tasks collection into a TaskViewModel. When I add a new task to the tasks collection, the CollectionObservable is updated as exptected.

I tried to create a selectedTasks attribute as a CollectionObservable with a filter option, like so:

this.selectedTasks = kb.collectionObservable(tasks, {
    view_model: function (task) {
        return new TaskViewModel(task);
    }, filters: function (task) {
        return task.isSelected(); // isSelected is undefined.
    }
});

But unfortunately, the object that gets passed to the filters function is not a TaskViewModel, but just a task object, so I have no access to the isSelected observable.

I couldn't find a lot about filtering a collection of view models instead of models. How can I created a selectedTasks observable that filters view models and doesn't create additional view models?

Joep
  • 305
  • 1
  • 6

1 Answers1

1

You can simply use computed observables:

this.selectedTasks = ko.computed(function() {
    return this.tasks().filter(function(task) {
        return task.isSelected();
    });
}, this);
manji
  • 47,442
  • 5
  • 96
  • 103