您可能应该做的是将您的视图模型逻辑与模板分离,将其封装在一个类中,然后将其传递给模板。这使您可以处理各种事情,例如将默认值设置为您需要的任何值(随着新列的添加或服务器端 JSON 结构的更改),并且还使视图模型更具可测试性。它还使您能够非常轻松地实现诸如客户端编辑/添加/删除行数据之类的事情。至于第 2 点,我相信在视图模型中将其设为 ko.observable 将解决此问题。
这是一个可能的实现的片段:
function TableDefinition(tableName, tableConfig, options) {
var self = this;
tableConfig = tableConfig || {};
// Create an instance of TableRow from each item in tableConfig
var initialItems = ko.utils.arrayMap(tableConfig || [],
function(item) { return new TableRow(item); });
self.config = ko.observableArray(initialItems);
self.tableName = ko.observable(tableName);
self.addRow = function() {
// Allows you to instantly add a new row right from your page without relying on
// the server-side structure
self.config.push(new TableRow());
};
self.deleteRow = function(row) {
self.config.remove(row);
}
}
function TableRow(data) {
var self = this;
data = data || {};
self.foo = ko.observable(data.foo || ''); // These are observables so that
self.bar = ko.observable(data.bar || ''); // you can bind the values from
self.baz = ko.observable(data.baz || ''); // control to view model
self.selections = ['val1', 'val2', 'val3', 'val4']
}
现在您可以将其添加到您的根视图模型中,并将来自服务器的数据直接传递到TableDefinition
视图模型中。
function RootViewModel(data) {
var self = this;
self.table = new TableDefinition('item-list-custom', data);
}
在您的页面上:
var dataFromServer = [
{foo: 'val1', bar: 'val1'},
{foo: 'val2', bar: 'val2'},
{foo: 'val3', bar: 'val3'},
{foo: 'val4', bar: 'val4'}]; // Dummy data, assumed to be retrieved from the server
var viewModel = new RootViewModel(dataFromServer);
ko.applyBindings(viewModel, document.getElementById('root'));
这是相关的 JsFiddle:http: //jsfiddle.net/dflor003/BM3HU/
底部有一个实时调试视图,其中包含您将以 JSON 形式发送回服务器的数据输出,当您更改值时会更新这些数据。