I’m trying to add a new item to an observable array when a button is clicked. I’m pretty much following this example on the knockout.js site:
http://knockoutjs.com/examples/betterList.html
Here’s the relevant HTML:
<form data-bind="submit:addItem">
<input id="comment" data-bind="value:itemToAdd.comment, valueUpdate: 'afterkeydown'" />
<input type="submit" value="Save contact" />
</form>
As you can see (this is the difference from the example), my “itemToAdd” will have multiple properties, one of them is “comment”. So I’m trying to bind it like this: “value:itemToAdd.comment” (I also tried “value:itemToAdd().comment”). But that doesn’t seem to work. Here’s the relevant part of my view model:
var viewModel = {
contactHistory: [{comment: 'test', date: '12/12/2011'}, {comment: 'test2', date: '12/11/2011'}],
itemToAdd: new ko.observable({ comment: 'dd', date: '' }),
addItem: function () {
alert(this.itemToAdd().comment);
if (this.itemToAdd().comment != "")
{
this.contactHistory.push(this.itemToAdd());
}
}
}
The alert always displays “dd”, so the itemToAdd doesn’t seem to be properly bound to the text box. Does anyone haven an idea what I’m doing wrong?
normally you would do
itemToAdd().comment, but KO actually isn’t able to write properly when the property in the data-bind is not an observable and is nested.You can certainly solve it by making
commentan observable like: http://jsfiddle.net/rniemeyer/mFkGT/. You would not need to haveitemToAddbe an observable in that case, if you didn’t want it to be.Another option would be to get into the scope of
itemToAddbefore binding againstcomment. In 1.3, you could use awith: itemToAddlike: http://jsfiddle.net/rniemeyer/SDAhd/. If you don’t want the extra span, then you can use a containerless binding like: http://jsfiddle.net/rniemeyer/ZmDwW/.Prior to 1.3, you could use the template binding with a
dataparameter to do something like: http://jsfiddle.net/rniemeyer/sb6vD/