Knockout - Item Wrapper Example
Contains: * simplified navigation * synchronous data-loading and -rendering
by plus5keen
HTML
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<div class="liveExample">
<div class="nav" data-bind="with: navModel">
<p>Nav Id: <input data-bind="value: activeItemId, valueUpdate: 'afterkeydown'" /></p>
<p>Edit Mode: <input type="checkbox" data-bind="" /></p>
</div>
<div class='browseView'>
<button data-bind="click: createItem">Create Item</button>
<h2 data-bind="text: sectionTitle"></h2>
<div data-bind="if: activeItem">
<!-- ko with: activeItem -->
<p>Id: "<!-- ko text: id -->not yet bound<!-- /ko -->"</p>
<div>
<div><label>First name</label></div>
<div><input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></div>
</div>
<div>
<label>First name again</label>
<div><input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></div>
</div>
<div>
<label>Last name</label>
<div><input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></div>
</div>
<h3>Hello, <!-- ko text: fullName -->not yet bound<!-- /ko -->!</h2>
<button data-bind="click: rebase">Rebase</button>
<!-- /ko -->
</div>
</div>
<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>
</div>
CSS
body { font-family: arial; font-size: 14px; }
.liveExample { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.liveExample input { font-family: Arial; }
.liveExample b { font-weight: bold; }
.liveExample p { margin-top: 0.9em; margin-bottom: 0.9em; }
.liveExample select[multiple] { width: 100%; height: 8em; }
.liveExample h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
JavaScript
(function () {
var _ = { // fake _ for compatibility
each: function (arr, fn) {
for(var i = 0, il = arr.length; i < il; i++) {
fn(arr[i]);
}
},
mapObject: function (obj, fn) {
var result = {};
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = fn(obj[key]);
}
}
return result;
}
};
var unwrap = ko.utils.unwrapObservable;
var createActionSet = function () {
var actions = [];
var actionSet = function () {
_.each(actions, function (action) {
action();
});
};
actionSet.add = function (action) {
actions.push(action);
};
return actionSet;
};
var createKOProp = function (target, key) {
var inner = ko.observable();
var result = ko.computed({
read: function () {
var lt = unwrap(target);
var value = lt ? lt[key] : void 0;
if (inner() !== value) {
inner(value);
}
return value;
},
write: function (value) {
var lt = unwrap(target);
inner(lt ? (lt[key] = value) : void 0);
}
});
return result;
};
var createKOArrayProp = function (target, key) { // TODO
var inner = ko.observableArray();
var result = ko.computed({
read: function () {
var lt = unwrap(target);
var value = lt ? lt[key] : void 0;
if (inner() !== value) {
inner(value);
}
return value;
},
write: function (value) {
var lt = unwrap(target);
inner(lt ? (lt[key] = value) : void 0);
}
...