質問
次のビューを検討してください。
<p>Count <span data-bind="text: unreadCount()"> </span></p>
<div data-bind='template: { name: "conversationTemplate", data: currentList }'> </div>
<script type="text/html" id="conversationTemplate">
<table>
<tbody>
{{each $data}}
<tr id="conversation_${conversation_id}" class="conversation-item ${status}">
<td><input type="checkbox" data-bind="click: function() { alert(this.value) }, checked: read" /></td>
</tr>
{{/each}}
</tbody>
</table>
</script>
と次のコード:
$(function() {
var viewModel = {
currentList : ko.observableArray([])
};
ko.dependentObservable(function () {
$.ajax({
url: '/conversations/inbox.json', dataType: 'json',
success: function(data) {
viewModel.currentList(data.conversationlist);
}
});
}.bind(viewModel));
viewModel.unreadCount = ko.dependentObservable(function() {
var unreadCount = 0;
for (var i = 0; i < viewModel.currentList().length; i++)
if (viewModel.currentList()[i].read == true) {
unreadCount++;
}
return unreadCount;
});
ko.applyBindings(viewModel);
上記は機能しているように見えますが、これを正しく構築したかどうかはわかりません。私がやり方を学びたいのは、あなたが変更したときです チェックボックス, 、どのように持っているか unreadCount
変更を反映するために自動的に更新されます。 KOを使用するとこれを自動的に提供すると思いましたが、テンプレートのチェックボックスデータバインドで何かをする必要があるかもしれません。
また、チェックボックスを変更して、ビューモデルと未読カウントを自動的に更新できるようになったら、その更新をサーバー(Rails)に戻す正しい方法は何ですか?
サーバーからのJSON応答の例は次のとおりです。
{
"conversationlist": [{
"project_name": "Proj 1",
"preview": "xxxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}, {
"project_name": "Proj 2",
"preview": "xxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}, {
"project_name": "Proj 3",
"preview": "xxxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}]
}
解決
関数を実行できるようです クリック (中身 data-bind='click: function() {...}'
)チェックされたチェックボックスの値に応じて、未読カウンターを増分または減少させる各アイテム。このように、あなたは決してループする必要はありません currentList
そのようにして未読カウントを更新します。
ビューモデルを購読することもできます read
プロパティを明示的に、自分のコードを実行するとき read
変更(「観測可能性を明示的に購読する」を参照してください 観測可能性のドキュメント).
編集: これがそうです 1人のユーザーが、観察可能なプロパティを備えたアイテムを備えた観測可能な配列をどのように設定するかを説明するスレッド。 ここ著者(Steve Sanderson)が観察可能な特性を持つ観測可能な配列を実証することを思いついた例です。
どちらの方法でも、Ajaxコールを実行してサーバーに投稿できるようです。
アップデート: :これを実装する方法の例は次のとおりです。
$(function() {
var initialData = {/*Data retrieved by AJAX or on page load*/};
var markRead = function(conversation) {
// Make AJAX POST here to update read status of
// the conversation
};
// Convenience object for conversations.
var Conversation = function(conversation_id, status, read) {
this.conversation_id = conversation_id;
this.status = status;
this.read = ko.observable(read);
};
var initialUnread = 0;
var viewModel = {
// Map the conversation list to a new array containing
// objects with observable properties.
conversationList: ko.observableArray(ko.utils.arrayMap(
initialData.conversationlist, function(data) {
if (!data.read === false) {
initialUnread++;
}
return new Conversation(
data.conversation_id,
data.status,
data.read);
})),
unreadCount: ko.observable(initialUnread),
// Executed when the user toggles a conversation's
// read status.
toggleRead: function(conversation) {
// Update the unread count.
viewModel.unreadCount(
viewModel.unreadCount() +
(conversation.read() ? 1 : -1));
// Update the conversation via AJAX
markRead(conversation);
return true;
}
};
ko.applyBindings(viewModel);
});
ノート:
- マッピングプラグインを使用しません。ただし、一般的なロジックは同じでなければなりません。
- Ajax呼び出しが失敗した場合、クリック前にチェックボックスをステータスで更新する必要があります。
- 更新できます
unreadCount
viewmodelのプロパティは、電話をかけてどこにでもありますviewModel.unreadCount(<value>)
. - これはいくつかの例に基づいています。 これです. 。複雑な例は、特に目を見張るものであり、KOでできるクールなことをいくつか示しています。