5

I have a ViewModel that looks like:

{
    empName: [
        { name: 'NAME1' },
        { name: 'NAME2' }
    ]        
}

I want to display different department names according to my empName while looping through name property using a switch statement. such that output is:

Department 1
Department 2

I tried the following:

<ul data-bind="foreach: empName">
        <div data-bind="switch: name">
        <div data-bind="case: 'Name1'">
            Department 1
        </div>
        <div data-bind="case: 'Name2'">
            Department 2
        </div>

        <div data-bind="case: $default">
        </div>
    </div>

But I get the following output:

Department 1
Department 2
Department 1
Department 2

How can I achieve this?

Carrie Kendall
  • 11,124
  • 5
  • 61
  • 81
ismail baig
  • 861
  • 2
  • 11
  • 39
  • I wonder KO has switch-case biding... So have a look at a library . Hope this helps [Git : knockout-switch-case](https://github.com/mbest/knockout-switch-case). Example borrowed from [Switch-Case-Not-Working](http://stackoverflow.com/questions/25017862/knockout-switch-case-plugin-is-not-hiding-showing-the-correct-value) is [**here**](http://jsfiddle.net/a5H92/1/) – Shubh Apr 24 '15 at 16:00
  • 1
    Put the switch case in the JS. Then just do a foreach on an array of strings in the HTML. – CrimsonChris Apr 24 '15 at 16:03
  • @CrimsonChris Fully agree. Keep the more lengthy/complex logic out of the bindings. I suggest this in my answer. – Carrie Kendall Apr 24 '15 at 16:32

3 Answers3

5

Why not rethink the problem a little and move this logic into a function? As a rule of thumb, I try to keep my bindings as simple as possible and put the logic into my javascript.

Here is a full example:

var viewModel = {
   empName: [
        { name: 'NAME1' },
        { name: 'NAME2' }
   ]        
};

viewModel.departmentName = function(name) {
    var departmentName = "Department ";

    switch (name) {
        case "NAME2":
            departmentName += "2";
            break;
        case "NAME1":
        default:
            departmentName += "1";
            break;
    }

    return departmentName; 
}.bind(viewModel);

ko.applyBindings(viewModel);

and then in your markup:

<ul data-bind="foreach: empName">
    <li data-bind="text: viewModel.departmentName(name)"></li>
</ul>

which outputs:

Department 1
Department 2

JSFiddle Demo


On a sidenote, if you really only have two cases (which I assume you don't and you just simplified for this post), then use a ternary operator in the departmentName function:
return name === "NAME2" ? "Department 2" : "Department 1";
Carrie Kendall
  • 11,124
  • 5
  • 61
  • 81
4

My two cents!! Knockout does not have a switch case statement. As suggested by RP Niemeyer

Michael Best's switch/case binding (https://github.com/mbest/knockout-switch-case) is quite flexible and can let you easily handle this and more complicated ones (more states than true/false).

Else you could use condition binding as :

    <!-- ko if: name == 'NAME1' -->
    <div data-bind="if: name == 'NAME1'">Department 1</div>
    <!-- /ko -->

Also,

<div data-bind="if: name == 'NAME1'">Department 1</div>

Demo

Community
  • 1
  • 1
Surabhi
  • 51
  • 3
3

There is no switch but you can use if:

<div data-bind="foreach: empName">
    <div data-bind="if: name == 'Name1'">
        Department 1
    </div>
    <div data-bind="if: name == 'Name2'">
        Department 2
    </div>
</div>
Konstantin Dinev
  • 34,219
  • 14
  • 75
  • 100