Knockout を使用してアプリケーションを作成していますが、非常に便利です。ただし、多次元配列 (オブジェクト) を観測可能にすることに問題があります。
現時点では、次の構造を使用しています。
self.form = ko.observableArray(ko.utils.arrayMap(initialData, function(section) {
var result = {
name : section.name,
code : section.code,
type : section.type,
fields: ko.observableArray(section.fields)
};
return result;
}));
うまく機能しますが、initialDataが 2 レベルを超えると機能しません。私は何かを試しました
self.form = ko.observableArray(ko.utils.arrayMap(initialData, function(block) {
var result = {
name : block.name,
code : block.code,
type : block.type,
sections: ko.observableArray(ko.utils.arrayMap(block.sections, function(section) {
var result = {
name : section.name,
code : section.code,
type : section.type,
fields: ko.observableArray(section.fields)
};
return result;
}))
};
return result;
}));
最終的な配列構造は良さそうに見えますが、セクション配列へのプッシュを行っているときにノックアウトは DOM を更新しません。
self.addField = function( section ) {
field = {
code: uid(),
name: "New Field",
value: '',
type: section.type
};
section.fields.push(field);
};
また、knockout.mapping.js プラグインを試してみました (それは正しいアプローチですか?) 最初は良さそうに見えますが、上記の関数をプッシュした後、新しいフィールド要素は観察できず、オブジェクトだけになります。
プラグインのドキュメントには次のように書かれています。
// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);
しかし、それが私の場合であるかどうかはわかりません。
誰かに何かアイデアがあれば、それは大歓迎です。
ありがとう。
UPD: 1 番目と 2 番目のレベルを観測可能にすることは問題ではありません。問題はさらに深くすることです。
以下はinitialDataの例です。
var blocks = [
{
"name" : "",
"sections" : [
{
"name" : "Section 1",
"fields" : [
{
"name" : "Field A",
"type" : "checkbox",
"code" : uid()
}
]
}
]
}
];
HTML
<div data-bind='template: { name: tpl-form-field-checkbox, foreach: fields }'></div>
<button class="btn addField" data-bind="click: $root.addField">Add</button>
<script type="text/html" id="tpl-form-field-checkbox">
<input type="text" name="" value="<%= name %>" /> <br/>
</script>