概要
KnockoutJsで、ネストしたforeachをつくることがあった。普通に作っただけだと、親配列しかバインドされないので、その子配列もふくめてko.observableする方法のメモ。
親配列の構造
以下の様な構造。このままだと、todoのオブジェクト自体はバインドされるが、todo.idなどはバインドされず、変更があっても検知されない。
function UserConf(user) {
var self = this;
self.id = ko.observable(user.id);
self.name = ko.observable(user.name);
self.todo = ko.observableArray(user.todo);
};
function UserViewModel() {
var self = this;
var userData = [
{ id: 1, name: "Tarou", todo: [{ id: 1, content: "aaa" }, { id: 2, content: "bbb" }, { id: 3, content: "ccc" }] },
{ id: 2, name: "Jirou", todo: [{ id: 4, content: "ddd" }, { id: 5, content: "eee" }, { id: 6, content: "fff" }] },
{ id: 3, name: "Shirou", todo: [{ id: 7, content: "ggg" }, { id: 8, content: "hhh" }, { id: 9, content: "iii" }] }
];
var mappedUser = $.map(userData, function(item, i) {
return new UserConf(item)
});
self.users = ko.observableArray(mappedUser);
};
ko.applyBindings(new UserViewModel());
子配列をobservableにする
以下では、new TodoConf();
で、todoの中身もobservableにしている。これにて、子配列もバインドされた(→デモ@jsfiddle)。
function UserConf(user) {
var self = this;
self.id = ko.observable(user.id);
self.name = ko.observable(user.name);
// 付け足し
user.todo = $.map(user.todo, function (item, i) {
return new TodoConf(item);
});
self.todo = ko.observableArray(user.todo);
};
// 付け足し
function TodoConf(todo) {
var self = this;
self.id = ko.observable(todo.id);
self.content = ko.observable(todo.content);
}
function UserViewModel() {
// そのまま
};
ko.applyBindings(new UserViewModel());
とおもったら。。
Mappingプラグインを使えば簡単に配列をバインドできるよう。次から使おう。