I am trying to update a KnockOutJS page using an Ajax call. The Update function should retrieve the Gifts Observable array from a web service. Shouldn’t this update the model, then the UI. I must be missing how this works. I ideas?
Thanks
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<tit
le>Index</title>
<link rel="Stylesheet" href="/Content/Site.css" />
<script type="text/javascript" src="/Scripts/jquery-1.4.2.js"></script>
<script type="text/javascript" src="/Scripts/jquery.validate.js"></script>
<script type="text/javascript" src="/Scripts/jquery.tmpl.js"></script>
<script type="text/javascript" src="/Scripts/knockout-1.2.1.js"></script>
<script type="text/javascript" src="/Scripts/knockout.mapping.js"></script>
<script type="text/javascript" src="/Scripts/json2.js"></script>
<script type="text/javascript" src="http://knockoutjs.com/examples/resources/sampleProductCategories.js">
</script>
</head>
<body>
<div>
<h1>Gift list editor 2</h1>
11/15/2011 12:55:32 PM <br />
<p>You have asked for <span data-bind="text: gifts().length"> </span> gift(s)</p>
<form class="giftListEditor" action="" >
<table style="width: 800px;">
<tbody data-bind="template: { name: 'giftRowTemplate', foreach: gifts }"></tbody>
</table>
<button data-bind="click: addGift">Add Gift</button>
<button data-bind="enable: gifts().length > 0" type="submit">Submit</button>
<button data-bind="click: update, enable: gifts().length > 0">Partial Update</button>
</form>
<script type="text/html" id="giftRowTemplate">
<tr>
<td style="width:100px;" >
<label data-bind="visible: GiftId == 0">New</label>
<label data-bind="text: 'GiftId: ' + GiftId, visible: GiftId > 0" />
</td>
<td><select data-bind='options: sampleProductCategories, optionsText: "name"' /></td>
<td>Gift name: <input class="required" data-bind="value: Title, uniqueName: true"/></td>
<td>Price: $ <input class="required number" data-bind="value: Price, uniqueName: true" /></td>
<td><a href="#" data-bind="click: function() { viewModel.removeGift($data) }">Delete</a></td>
</tr>
</script>
<script type="text/javascript">
var initialData = [{"GiftId":13,"Title":"test","Price":3},{"GiftId":15,"Title":"asdasd","Price":444},{"GiftId":44,"Title":"asd","Price":1},{"GiftId":45,"Title":"asdasd","Price":1231},{"GiftId":46,"Title":"qwe","Price":132},{"GiftId":47,"Title":"eeee","Price":123123},{"GiftId":48,"Title":"www","Price":121212}]; //var initialData = [{ GiftId: "","Title": "Tall Hat", "Price": 49.95 }, { GiftId: "","Title": "Long Cloak", "Price": 78.25}];
var viewModel = {
gifts: ko.observableArray(initialData),
addGift: function () {
this.gifts.push({ GiftId: "0", Title: "", Price: "" });
},
removeGift: function (gift) {
this.gifts.remove(gift);
},
update: function () {
$.ajax({
url: "/Home/PartialUpdate",
success: function(result){
this.gifts = ko.utils.parseJson(result); //[{ GiftId: "33", Title: "ThirtyThree", Price: "10.50" }]
alert(this.gifts.length);
},
error:function(xhr,err){
alert("readyState: " + xhr.readyState+"\nstatus: "+xhr.status);
alert("responseText: " + xhr.responseText);
}
});
},
save: function() {
ko.utils.postJson(location.href, { gifts: this.gifts });
}
};
ko.applyBindings(viewModel, document.body);
$("form").validate({ submitHandler: function() { viewModel.save() } });
</script>
</div>
</body>
</html>
this.giftsis an observableArray. When you set the updated value, you need to set it as an observable:The current code that you have is setting gifts equal to a new array that is not observable or currently bound against the UI.
You may also need to be careful with
thisin your success function. Ifthisis not appropriate, then you could choose to add acontext: viewModelto your $.ajax options.