AnswerGroupオブジェクトの配列を持つviewModelがあります。 answerGroupオブジェクトの1つのフィードバックプロパティが更新されたら、ajax経由でASP.Net MVCアプリに渡すことで、更新されたオブジェクトをデータベースに保存したいと思います。
通常の保存ボタンやリンクを使用する代わりに、オブジェクトのプロパティが更新されたときにオブジェクトをAjax呼び出しに渡す必要があります。 textarea要素のchangeイベントにバインドすることでこれを実行できると思いましたが、これを実行するとajax関数が呼び出されますが、基になるanswerGroupオブジェクトのフィードバックプロパティは更新されません。
Knockout1.2.1を使用しています。以下はJavaScriptコードです。HTMLは含めていません。
私はこれを間違った方法で行っているのですか、それともknockout.jsイベントバインディングの構文が間違っているだけですか?
<script>
var viewModel = {}
$(function () {
viewModel.scenarioId = ko.observable($("#Scenario_ScenarioID").val());
viewModel.answerGroups = ko.observableArray([]);
viewModel.addGroup = function (answerGroup) {
// add item to beginning of array
this.answerGroups.unshift(answerGroup);
};
ko.applyBindings(viewModel);
});
function answerGroup() {
this.id = ko.observable();
this.name = ko.observable();
this.feedback = ko.observable();
// the groups feedback has been updated so save
// these details back to the server
this.updateGroup = function (event) {
// javascript api library that is an ajax function.
// this works without a problem.
api.updateAnswerGroup({
success: function (result) {
alert("saved!");
},
error: function (e) {
alert("error!");
},
data: "answerGroupId=" + this.id + "&feedback=" + this.feedback
});
return true;
};
}
</script>
<script id="answerGroupsTemplate" type="text/html">
<div>
<h4><a href='#'>${ $data.name }</h4>
<div>
<textarea cols="100" rows="2" data-bind="event: { text: feedback, change: updateGroup }">
</textarea>
</div>
</div>
</script>
Knockoutでこれを処理する一般的な方法は、変更に対応するオブザーバブルで手動サブスクリプションを実行することです。
したがって、次のようなことを行います。
function answerGroup() {
this.id = ko.observable();
this.name = ko.observable();
this.feedback = ko.observable();
this.feedback.subscribe(function (newValue) {
//run your update code here
}, this);
}
サブスクライブ関数の2番目のパラメーターは、関数の実行時にコンテキスト( "this")を制御します。
このようなサブスクリプションの良いところは、オブザーバブルがプログラムで変更されたとき、またはUIのバインディングに基づいて変更されたときに起動することです。
ここでの簡単なドキュメント: http://knockoutjs.com/documentation/observables.html#explicitly-subscribing-to-observables
手動サブスクリプションの使用に関する情報を含む投稿がありました ここ も。
お役に立てれば。
私はRPNiemeyerが説明するようにオブザーバブルをサブスクライブすることを好みますが、場合によっては、オブザーバブルではなくイベントにアタッチする必要があります。したがって、「イベント」バインディングを使用できます。ドキュメントには「change」イベントは含まれていませんが、バージョンv2.0.0rcで試してみましたが、機能します。
<input data-bind="value: viewModel.MyProperty, event: { change: viewModel.MyPropertyChanged } />