Init viewModel: Binding to specific array element Options

http://groups.google.com/group/knockoutjs/browse_thread/thread/c910d9d9b29253bf

by gurkavcu

HTML

<script src="https://github.com/downloads/SteveSanderson/knockout/jquery.tmpl.js"></script>
<script src="http://github.com/downloads/SteveSanderson/knockout/knockout-1.1.2.js"></script>
<div id="main">
    <p><span class="price" data-id="1">9</span>  <span class="status" data-id="1"></span></p>
    <p><span class="price" data-id="2">18</span>  <span class="status" data-id="2"></span></p>
    <p><span class="price" data-id="3">32</span>  <span class="status" data-id="3"></span></p>
    <p><span class="price" data-id="4">36</span>  <span class="status" data-id="4"></span></p>
</div>

<button onclick="update()">Update</button>

JavaScript

//start with empty viewModel
var viewModel = {
    prices: []
};

//construct a priceItem
function priceItem(id, price) {
    this.id = ko.observable(id);
    this.price = ko.observable(price);
    this.status = ko.dependentObservable(function() {
        return this.price() > 50 ? "invalid" : "";
    }, this);
}
    
$(function() {
    //initialize the viewModel from loaded page
    $("#main p").each(function(index, value) {
        var priceElem = $(value).children(".price");
        var statusElem = $(value).children(".status");
        
        var item = new priceItem(priceElem.attr("data-id"), priceElem.text());

        //viewModel.prices.push(priceItem);
        viewModel.prices[item.id()] = item;
        
        $(priceElem).attr("data-bind", "text: price");
        $(statusElem).attr("data-bind", "text: status");
        
        ko.applyBindings(item, value);
    });
});

function update() {
    var updates = getFakeUpdates();
    $.each(updates, function(index, value) {
        var matched = viewModel.prices[value.id];
        //var matched = ko.utils.arrayFirst(viewModel.prices, function(item) {
        //    if (item.id() == value.id) { return item } else { return null }
        //});
        matched.price(value.price);
    });
};

function getFakeUpdates() {
    return [{
        id: Math.ceil(4 * Math.random()),
        price: Math.ceil(100 * Math.random())
    }, {
        id: Math.ceil(4 * Math.random()),
        price: Math.ceil(100 * Math.random())
    }];
}