JSFiddle - React, Tailwind, and code Playground
by OlsonDev
HTML
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.debug.js"></script>
<p id="instructions">
<strong>Instructions:</strong> Note the select shows "foo1". Note the "changelog" output; immediately something looks wrong. bar1's <code>fooId</code> changed twice. Initially its value was 1. Then a <code>change</code> event was fired, which changed its value to an empty string. If you click bar2, you'll see bar2's <code>fooId</code> value change to an empty string. However, the select will display "foo2". Switch back to bar1. The select now is updated to reflect the (erroneously updated) model. Click bar2; you'll see the same change.
</p>
<div data-bind="foreach: bars">
<button type="button" data-bind="click: $root.setActiveBar, text: name(), css: { active: $data == $root.activeBar() }"></button>
</div>
<div data-bind="with: activeBar">
<select data-bind="value: fooId">
<option value="">-- Select a foo --</option>
<!-- ko foreach: $root.foos -->
<option data-bind="value: id, text: name"></option>
<!-- /ko -->
</select>
</div>
<textarea id="changelog"></textarea>
CSS
button {
color: #888;
background-color: #DDD;
border: 1px solid #ABADB3;
border-radius: 2px;
font-size: 16px;
padding: 5px 20px;
}
button:hover {
color: #666;
}
button.active {
color: #000;
}
#changelog {
display: block;
width: 300px;
height: 300px;
}
#instructions {
font-family: sans-serif;
margin: 5px;
max-width: 500px;
}
strong {
font-weight: bold;
}
JavaScript
function Foo(id, name) {
var self = this;
self.id = ko.observable(id);
self.name = ko.observable(name);
}
function Bar(id, name, fooId) {
var self = this;
self.id = ko.observable(id);
self.name = ko.observable(name);
self.fooId = ko.observable(null);
self.fooId.subscribe(function(newFooId) {
$('#changelog').append(self.name() + ".fooId changed to: " + newFooId + '\n');
});
self.fooId(fooId);
}
function ViewModel() {
var self = this;
self.foos = ko.observableArray([]);
self.foos.push(new Foo(1, 'foo1'));
self.foos.push(new Foo(2, 'foo2'));
self.bars = ko.observableArray([]);
self.bars.push(new Bar(1, 'bar1', 1));
self.bars.push(new Bar(2, 'bar2', 2));
self.bars.push(new Bar(2, 'bar3', 1));
self.bars.push(new Bar(2, 'bar4', 2));
self.activeBar = ko.observable(self.bars()[0]);
self.setActiveBar = function(bar) {
self.activeBar(bar);
};
}
ko.applyBindings(window.vm = new ViewModel());