6
votes

I use foreach on an observable array:

<div id="mainRight" data-bind="foreach: notifications">
    <div class="statusRow">
        <div class="leftStatusCell">
            <div class="leftStatusCellColor" data-bind="css: availabilityCssClass($data.availability)"></div>
        </div>
        <div class="topRightStatusCell" data-bind="text: sip"></div>
        <div class="bottomtRightStatusCell ellipsisSingleline" data-bind="text: note"></div>
    </div>
</div> <!== end mainRight ==>

As you can see, I pass the current value of availability to the function availabilityCssClass, which compares the value to some predefined strings. Depending on the matching string, it returns a class name.

self.availabilityCssClass = ko.computed(function (value) {
    var availability = value;
    if (availability === "Busy" || "DoNotDisturb" || "BeRightBack")
        return "leftStatusCellColorOrange";
    else if (availability === "Away" || "Offline")
        return "leftStatusCellColorRed";
    else
        return "leftStatusCellColorGreen";
});

This is my model. The data comes from an external data source.

function Notification(root, sip, availability, note) {
    var self = this;

    self.sip = ko.observable(sip);
    self.availability = ko.observable(availability);
    self.note = ko.observable(note);
};

self.notifications = ko.observableArray();

However, it doesnt work as is. When the computed function is not commented out, the foreach does not iterate over the data and the div is empty. But I can see that the viewModel is not empty.

3
Can you provide a fiddle, and describe what doesn't work.Jan Hančič
Which KO version are you using?nemesv
Im using 2.2 so this functionality should be supported, right?mupersan82
The class is not applied according to evaluated value.mupersan82

3 Answers

4
votes

You cannot pass value into computed in such way. It is better to add this computed to Notification view model and use self.availability property:

function Notification(root, sip, availability, note) {
    var self = this;

    self.sip = ko.observable(sip);
    self.availability = ko.observable(availability);
    self.note = ko.observable(note);

    self.availabilityCssClass = ko.computed(function() {
        var availability = self.availability();

        if (["Busy", "DoNotDisturb", "BeRightBack"].indexOf(availability) != -1) return "leftStatusCellColorOrange";
        else if (["Away", "Offline"].indexOf(availability) != -1) return "leftStatusCellColorRed";
        else return "leftStatusCellColorGreen";
    });
};

Your if statement wasn't correct, so I fixed the logic. Here is working fiddle: http://jsfiddle.net/vyshniakov/Jk7Fd/

1
votes

You just need to make availabilityCssClass a function. As you've written it, it's not a computed observable since it has no observable dependencies.

self.availabilityCssClass = function (value) {
    var availability = value;
    if (availability === "Busy" || "DoNotDisturb" || "BeRightBack")
        return "leftStatusCellColorOrange";
    else if (availability === "Away" || "Offline")
        return "leftStatusCellColorRed";
    else
        return "leftStatusCellColorGreen";
};
0
votes

The CSS binding wants a object literal with the name of the CSS class as member name and the value true or false depeding on you want to remove or add the class

data-bind="css: { 'css-class-name': true }"

edit: Hmm, they have changed the css binding in 2.2 ;)