2012-09-20 44 views
0

所设置的新键:处理在数据绑定

我有一个显示使用模板表一knockout.js应用“的foreach:$ data.items”。

数据设定与数据绑定像这样的$:

<div data-bind="template: {name: 'table-custom', data: {table: 'item-list-custom', config: $root.items, default: {foo: '', bar: ''}}}"></div> 

的$ root.items是http://stardict.sourceforge.net/Dictionaries.php下载的阵列,像这样:

[{foo: 'val2', bar: 'val2'}, ...] 

我得到的值JSON中的$ root.items,并根据模板创建表。

问题:

我想一个新列添加到表中,所以我增加了一个默认值“默认”字典(例如巴兹:“”)。新列呈现为选择(下拉列表)。

一切都可以做到这一点。我的问题是:

1)如何设置所选选项的值如果可用?我试图

<select data-bind="value: baz, ... 

但投诉,因为现有的行(从JSON)还不包含巴兹关键,所以它不能找到它。

2)当我在选择中选择一些值时,对于现有的行,它不会与模型的其余部分一起保存。即他们仍然只包含“foo”和“bar”键。

如果我在表中添加一个新行,然后选择一个值,它就可以正常工作,并将baz值与其他值一起保存。我想这是因为“默认”baz值为新行开始,而不是现有的行。

那么,如何让我的现有数据(在加载时没有“baz”属性,因为我稍后将其添加到表中)与新行一样使用此设置?

回答

0

您应该能够通过$data前面加上你的属性做到这一点:

<select data-bind="value: $data.baz, ... 

我创建了一个小型的jsfiddle演示:http://jsfiddle.net/amtiskaw/HD2jt/

+0

谢谢。这适用于(1)问题,但不适用于(2)。 – Hejazzman

+0

我不明白,从你的描述(2)它听起来像属性没有被填充,如果它最初未定义在行中。在我的JsFiddle中,列表中的第二项没有定义myProp,但是这个属性可以通过select来设置,并且会保存回底层对象,如点击“show'em”按钮所示。我不明白还需要什么? –

0

什么你应该做的是从分离您的视图模型逻辑该模板将其封装在一个类中,然后将其传递给模板。这可以让你处理各种事情,比如默认值,无论你需要什么(当新的列被添加或者服务器端的JSON结构发生变化时),并且它也使得视图模型更加可测试。它还使您能够轻松实现客户端编辑/添加/删除行数据等操作。至于第二点,我相信在视图模型中将它设置为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格式的服务器在更改值时会更新。

相关问题