2012-09-20 45 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格式的服務器在更改值時會更新。

相關問題