具有动态可观察量和html模板的淘汰网格

时间:2015-05-22 09:41:41

标签: javascript jquery html knockout.js

我正在尝试使用动态observables和html模板实现淘汰网格。

JSFiddle就在这里。

我创建,读取和写入两个模板。当单击单元格时,它应该转换为可编辑模式。但它应用编辑模板来完成列。 有人可以帮忙吗?

var DynamicObservable = function(data) {
    for (var key in data) {
        this[key] = ko.observable(data[key]);
    }
    
    selectedCell = ko.observable();
    
    templateToUse = function(item) {
        return item === this.selectedCell() ? 'write' : 'read';
    };
};

var ViewModel = function(data) {
    var self = this;
    self.items = ko.observableArray(ko.utils.arrayMap(data, function(i) {
        return new DynamicObservable(i);
    }));
    self.columns = ko.observableArray();
    for (var key in data[0]) {
        self.columns.push(key);
    }
    
    self.cellClick = function(){
        debugger;
        
    };
}

var init = [
    { name: "John", age: 23, weight: 145 },
    { name: "Tim", age: 25, weight: 143 },
    { name: "Alex", age: 22, weight: 142 }
];

ko.applyBindings(new ViewModel(init));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<b>Click on cell to edit</b>

<table>
    <thead>
        <tr data-bind="foreach: columns">
            <th data-bind="text: $data"></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: { data: items, as: 'item'}">
        <tr data-bind="foreach: $parent.columns">
            <td data-bind="template: { name: templateToUse }, event:{click:selectedCell}"> </td>
        </tr>
    </tbody>
</table>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

<script id="read" type="text/html">
    <div data-bind="text: item[$data]"></div>    
</script>

<script id="write" type="text/html">
    <input type="text" data-bind="value: item[$data]"/>  
</script>

1 个答案:

答案 0 :(得分:1)

我相信这可以简化,但它正在发挥作用。以前没有检查&#34; templateToUse&#34;点击了哪一行的功能。

更新了JSFiddle here

&#13;
&#13;
var DynamicObservable = function(data, rowIndex, parentSelectedRowIndex,parentSelectedColumnName) {
    self = this
    for (var key in data) {
        self[key] = ko.observable(data[key]);
    }
    
    self.selectCell = function(columnName) {
        parentSelectedRowIndex(rowIndex)
        parentSelectedColumnName(columnName)
    }
    
    self.templateToUse = function(columnName) {
        return rowIndex == parentSelectedRowIndex() && columnName == parentSelectedColumnName () 
                        ? 'write' : 'read';
    };
};

var ViewModel = function(data) {
    var self = this;
    
    self.parentSelectedRowIndex = ko.observable(null);
    self.parentSelectedColumnName = ko.observable(null);
    
    self.items = ko.observableArray(ko.utils.arrayMap(data, function(i) {
        var myIndex = data.indexOf(i);
        return new DynamicObservable(i, myIndex, self.parentSelectedRowIndex, self.parentSelectedColumnName);
    }));
    self.columns = ko.observableArray();
    for (var key in data[0]) {
        self.columns.push(key);
    }
    
    self.cellClick = function(){
        debugger;
        
    };
}

var init = [
    { name: "John", age: 23, weight: 145 },
    { name: "Tim", age: 25, weight: 143 },
    { name: "Alex", age: 22, weight: 142 }
];

ko.applyBindings(new ViewModel(init));
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<b>Click on cell to edit</b>

<table>
    <thead>
        <tr data-bind="foreach: columns">
            <th data-bind="text: $data"></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: { data: items, as: 'item'}">
        <tr data-bind="foreach: $parent.columns">
            <td data-bind="template: { name: item.templateToUse }, event:{click:item.selectCell}"> </td>
        </tr>
    </tbody>
</table>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

<script id="read" type="text/html">
    <div data-bind="text: item[$data]"></div>    
</script>

<script id="write" type="text/html">
    <input type="text" data-bind="value: item[$data]"/>  
</script>
&#13;
&#13;
&#13;

通过&#34; parentSelected&#34;有点凌乱。周围的观察,如果我想到一个更好的方法,我会发布更新。