String Array Binding Doesn't Update ViewModel

138 views
Skip to first unread message

Shaun Brown

unread,
Mar 2, 2012, 6:35:12 PM3/2/12
to KnockoutJS
I modifed the Gifts List sample to use an array of strings and $data
instead of property names but when I edit the entries the viewModel
doesn't update.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
TR/html4/strict.dtd">
<html>
<head>
<title>knockout</title>
<script type="text/javascript" src="knockout-2.0.0.js"></script>
</head>
<body>

<form action='/someServerSideHandler'>
<p>You have asked for <span data-bind='text:
gifts().length'>&nbsp;</span> gift(s)</p>
<table data-bind='visible: gifts().length > 0'>
<thead>
<tr>
<th>Gift name</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: gifts'>
<tr>
<td><input class='required' data-bind='value: $data,
uniqueName: true' /></td>
<td><a href='#' data-bind='click:
$root.removeGift'>Delete</a></td>
</tr>
</tbody>
</table>
<button data-bind='click: addGift'>Add Gift</button>
<button data-bind='enable: gifts().length > 0, click: save'
type='submit'>Submit</button>
</form>

<script type='text/javascript'>
var GiftModel = function(gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);

self.addGift = function() {
self.gifts.push("test");
};

self.removeGift = function(gift) {
self.gifts.remove(gift);
};

self.save = function(form) {
alert("Transmit to server: " +
ko.utils.stringifyJson(self.gifts));
};
};
var data = ["Tall Hat", "Long Cloak"]
var viewModel = new GiftModel(data);
ko.applyBindings(viewModel);
</script>

</body>
</html>

Shaun Brown

unread,
Mar 4, 2012, 12:28:01 PM3/4/12
to KnockoutJS

I take it you can only bind to an array of objects then; not an array
of strings if you want the viewmodel to update?

rpn

unread,
Mar 4, 2012, 3:36:43 PM3/4/12
to knock...@googlegroups.com
You are right.  

If you have items: ["one", "two", "three"] or even [ko.observable("one"), ko.observable("two"), ko.observable("three")] within a foreach $data will be the raw value and KO has no way at that point to know how to write back to it.  You need to use objects with properties, in the case that you need to read/write access to the value.

Shaun Brown

unread,
Mar 4, 2012, 4:23:19 PM3/4/12
to KnockoutJS
Thank you for confirming this. It might be useful for the
documentation to indicate that the $data idiom is read-only and not
suitable for read/write binding. We have got round this by coercing
our server to output JSON as an array of objects with one property for
the string value - a little more verbose but perfectly serviceable.
Reply all
Reply to author
Forward
0 new messages