ASP.NET MVCでKnockoutJSを使用していますが、ko.mappingを使用するとバインディングが壊れて問題が発生します。私のビューには、EnterキーをViewModelのメソッドにバインドするテキスト領域があります(基本的に、Enterキーを押して送信します)。
私は次のカスタムバインディングを持っています:
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);
}
});
}
};
ビューコードは次のようになります。
<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>
channelContentをko.observable()として作成する場合:
self.channelContent = ko.observable();
そして私はそれに次を入力します:
$.post('@Url.Action("Content", "Channel")', { channelId: channel.Id }, self.channelContent);
その後、すべてが正常に機能し、EnterはonMessageEnterKeyメソッドを適切に呼び出します。残念ながら、channelContentには監視可能にしたいネストされたプロパティがいくつかあるため、ko.mappingを使用しようとしています。
ko.mappingを使用する場合:
self.channelContent = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model.Channel)));
コンテンツを次のように更新します。
$.post('@Url.Action("Content", "Channel")', { channelId: channel.Id }, function(result) {
ko.mapping.fromJS(result, self.channelContent); // update the channel content
});
次に、他のすべてのバインディングは正常に機能しているように見えますが(基になるモデルを更新すると、UIが正しく変更されます)、enterKeyバインディングは機能しなくなります。発火することはありません。
つまり、channelContentを単純なko.observableからko.mappingから初期化するように変更するだけで、enterKeyが壊れます。