KevDog
KevDog

Reputation: 5803

How do I construct the proper view model (with multiple dependencies) in KnockoutJS?

Here is a subset of the markup I am using:

<div id="item_one"></div>
<div id="item_two"></div>
<div id="item_three"></div>

<p id="result_one">0</p>
<p id="result_two">0</p>
<p id="result_three">0</p>

The desired behaviors are:

  1. When you click a div, the corresponding text of the p tag is toggled from 0 to 1.
  2. The text of the p tags is to be concatenated into a string, e.g., click the second item and the resulting string would be "010".
  3. There is an array of eight items, with binary strings as the key. As clicks are made, the selected item in the array changes.

This seems like a good use of knockout, but I am a complete noob. How do I set up the proper dependencies?

Upvotes: 1

Views: 200

Answers (2)

RP Niemeyer
RP Niemeyer

Reputation: 114792

Here is a sample for one way to do it: http://jsfiddle.net/rniemeyer/XqDsy/

For convenience, I created a little "binaryObservable" that exposes a toggle function.

function binaryObservable(initialValue) {
   var result = ko.observable(initialValue);
   result.toggle = function() {
       result(result() === "1" ? "0" : "1");    
   };
   return result;
}

function ViewModel() {
   this.one = binaryObservable("0");
   this.two = binaryObservable("0");
   this.three = binaryObservable("0"); 

   this.combined = ko.dependentObservable(function() {
      return this.one() + this.two() + this.three();       
   }, this);

   this.choices = {
        "000": { id: 0, value: "000" },
        "001": { id: 1, value: "001" },
        "010": { id: 2, value: "010" },
        "011": { id: 3, value: "011" },
        "100": { id: 4, value: "100" },
        "101": { id: 5, value: "101" },
        "110": { id: 6, value: "110" },
        "111": { id: 7, value: "111" }
   };

   this.selectedChoice = ko.dependentObservable(function() {
       var combined = this.combined();
       return combined ? this.choices[combined] : {};
   }, this);   
}

ko.applyBindings(new ViewModel());

Then the HTML might look like:

<div id="item_one" data-bind="click: one.toggle">option one</div>
<div id="item_two" data-bind="click: two.toggle">option two</div>
<div id="item_three" data-bind="click: three.toggle">option three</div>

<hr/>

<p id="result_one" data-bind="text: one">0</p>
<p id="result_two" data-bind="text: two">0</p>
<p id="result_three" data-bind="text: three">0</p>

<hr/>

<p data-bind="text: combined"></p>

<hr/>

Selected choice: <span data-bind="text: selectedChoice().id"></span>

Upvotes: 5

Richard Friend
Richard Friend

Reputation: 16018

Im far from an expert but something like this ? jsFiddle

Upvotes: 1

Related Questions