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.
Shot in the dark, without more code or jsfiddle it’s hard to tell.
I’ve seen scenarios where the mapping plugin fails to update if you don’t use the 3 argument update method.
Try this.
As an aside, I would avoid the with binding,it’ performs terribly.
EDIT
Actually, here is a jsfiddle and it works for me either way. If you can update to show what’s different in your situation, I can probably help.
http://jsfiddle.net/madcapnmckay/52aMw/4/
Hope this helps.