I'm using KnockoutJS with ASP.NET MVC, and I'm having a problem with broken bindings when I use ko.mapping. On my view, I have a text area that I want to bind the enter key to a method on my ViewModel (enter to submit, basically).
I have the following custom binding:
ko.bindingHandlers.enterKey = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
ko.utils.registerEventHandler(element, 'keydown', function(evt) {
if (evt.keyCode === 13) {
evt.preventDefault();
evt.target.blur();
valueAccessor().call(viewModel);
}
});
}
};
and my view code looks like:
<div class="content-area" id="container" data-bind="with: channelContent">
// other code, to show content from channelContent
<textarea rows="1" cols="1" data-bind="value: $root.message, enterKey: $root.onMessageEnterKey"></textarea>
</div>
If create channelContent as a ko.observable():
self.channelContent = ko.observable();
and I populate it with:
$.post('@Url.Action("Content", "Channel")', { channelId: channel.Id }, self.channelContent);
then everything works fine and enter will properly call my onMessageEnterKey method. Unfortunately, because there are some nested properties in channelContent that I want to be observable, I'm trying to use ko.mapping.
If I use ko.mapping:
self.channelContent = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model.Channel)));
and update content with:
$.post('@Url.Action("Content", "Channel")', { channelId: channel.Id }, function(result) {
ko.mapping.fromJS(result, self.channelContent); // update the channel content
});
Then while all other bindings seem to work fine (updating the underlying model changes the UI correctly), the enterKey binding stops working. It never fires.
In other words, just changing channelContent from a simple ko.observable, to initialized from ko.mapping, breaks enterKey.