danswain
danswain

Reputation: 4177

KnockoutJs paramatized dependentObservable Array

I have a viewModel with an observableArray that gets updated from the server, then I need to be able to define a dynamic number of divs to filters of that observableArray.

It's a scrum board example, So imagine you receive an array of stories back from the server. and you add the to viewModel.stories() observableArray.

I'd like to have template bound filters for various different values of a property of each story within the observable array.

So given

item.BoardState is "Backlog" or "In Progress"

I want a dependent observable that I can paramatize to only show stories that are "In Progress"

    self.filterInProgress = ko.dependentObservable(function (filterParameter) {
    return ko.utils.arrayFilter(self.stories(), function (item) {
        console.log("Current Filter = " + filterParameter + "--- Current BoardState = " + item.BoardState);
        return ((item.BoardState === filterParameter));
    });
});

Unfortunately it says it doesn't work. any suggestions greatly appreciated.

Upvotes: 1

Views: 1204

Answers (3)

Andreas Helgegren
Andreas Helgegren

Reputation: 1668

I would write it like this:

View:

<div data-bind="foreach: filterInProgress">
    <h1 data-bind="text: Id"></h1>
</div>

ViewModel:

var viewModel = {

    stories: ko.observableArray(
        [
            {
                'Id': 0,
                'BoardState': 'In Progress'
            },
            {
                'Id': 1,
                'BoardState': 'Backlog'
            },
            {
                'Id': 2,
                'BoardState': 'In Progress'
            }            
        ]
    )
};

viewModel.filterInProgress = ko.computed(
    function() {
        return ko.utils.arrayFilter(viewModel.stories(), function(item) {
            return item.BoardState == 'In Progress';
        });
    }
)

ko.applyBindings(viewModel);

EDIT: now works as an ko.dependentObservable (ko.computed in 2.0)

Upvotes: 0

seth.miller
seth.miller

Reputation: 1988

You can always move the filter out to a separate function and create a dependentObservable for each filterType:

function filterStories(stories, filterParameter) {
    return ko.utils.arrayFilter(stories, function (item) {
        console.log("Current Filter = " + filterParameter + "--- Current BoardState = " + item.BoardState);
        return ((item.BoardState === filterParameter));
    });
}

self.filterInProgress = ko.dependentObservale(function() {
    return filterStories(self.stories(), "InProgress");
});

self.filterBacklog = ko.dependentObservale(function() {
    return filterStories(self.stories(), "Backlog");
});

Upvotes: 2

AlfeG
AlfeG

Reputation: 1473

Move parameter to View-Model and use custom bindings. So You will have no problem with it.

Look for this example that were born while I discuss this question with my college some time ago.

Demo - http://jsbin.com/epojol/5

Code with preview - http://jsbin.com/epojol/5/edit#javascript,html,live

Custom binding from demo:

ko.bindingHandlers.rangeVisible = {
            update: function (element, valueAccessor, allBindings) {
                var selectedValue = ko.utils.unwrapObservable(valueAccessor());
                var itemRange = allBindings().range;

                if (selectedValue < itemRange.max && selectedValue >= itemRange.min)
                    $(element).show("slow");
                else
                    $(element).hide("slow");
            }
        };

Binding in html:

<div class="plan red" data-bind="rangeVisible: selected, range: {min: 0, max:10}">

Upvotes: 0

Related Questions