【问题标题】:Knockout JS: Creating dynamic table columnsKnockout JS:创建动态表列
【发布时间】:2018-09-01 03:35:32
【问题描述】:

使用 Knockout JS:

我有一个要求。

我有一个包含 2 个静态列的表格,每个列都有一个文本框。我在表格外还有一个添加行按钮,每行都有一个删除行按钮。

当用户点击添加行时,它会在表格中添加一行,我可以看到两列,每列都有文本框。如果需要,用户可以通过单击添加行来添加更多行,然后单击删除行以删除行。

这一切都已设置好,可以正常工作:

https://jsfiddle.net/aman1981/xmd1xobm/14/

我的问题是还有一个获取列按钮。当用户单击此按钮时,我会获取一个列列表,并希望将这些列与表中现有列的标题添加到表中。这些列中的每一个也需要有一个文本框。

例如,我将列列表为:

 var columnsList = 'name, address, zip';

我不确定如何动态添加列。非常感谢您的意见。

这是我的桌子的设置:

<table class="table table-bordered">
  <thead class="mbhead">
<tr class="mbrow">
  <th>SIID</th>
  <th>Comment</th>      
</tr>
  </thead>
  <tbody data-bind="foreach: data">
   <tr>
    <td>
     <input type="text" data-bind="text: SIID" class="form-control textbox" />
  </td>      
  <td> 
   <input type="text" data-bind="text: Comment" class="form-control textbox" />
  </td>  
   <td>
    <input type="button" value="Remove Row" data-bind="click: $parent.removeRow" class="btn btn-danger" />
  </td>
</tr>
 </tbody>

<div class="col-xs-12 col-sm-6">
 <input type="button" value="Add Row" class="btn btn-primary" data-bind="click: addRow" /> 
  <input type="button" value="Get Columns" class="btn btn-primary" data-bind="click: addColumns" /> 
</div>

有人吗?

【问题讨论】:

  • 有趣的问题,首先你应该让你的 html in thead,tbody 动态。在视图中使用 data-bind="html://your html from vm" 并在添加行/列单击框架您的 html 并将其推送到查看。
  • @aman 让我知道您是否可以正常工作。我也在寻找这样的解决方案
  • @supercool 你有这方面的例子吗

标签: javascript knockout.js


【解决方案1】:

很高兴我有一个来自我之前项目的动态表格组件:

var observable = ko.observable;
var pureComputed = ko.pureComputed;
var observableArray = ko.observableArray;
var unwrap = ko.unwrap;

var data = observableArray([{
  a: 123,
  b: 234,
  c: 345
},{
  a: 1231,
  b: 2341,
  c: 3451
},{
  a: 1232,
  b: 2342,
  c: 3425
},{
  a: 1233,
  b: 2343,
  c: 3453
}]);

var columns = observableArray([{
    field: "a",
    displayName: "A"
},{
    field: "b",
    displayName: "B (i can even change the title)"
}])

function viewModel(params) {
    var paramColumns = params.columns;
    var paramData = params.data;
    var paramFieldKey = params.fieldKey || "field";
    var paramDisplayNameKey = params.displayNameKey || "displayName";

    var koColumnHeaders = pureComputed(function () {
        var columns = paramColumns();
        var columnHeaders = [];
        var fieldKey = unwrap(paramFieldKey);
        var displayNameKey = unwrap(paramDisplayNameKey);
        for (var i in columns) {
            var column = columns[i];
            columnHeaders.push({
                field: column[fieldKey],
                displayName: column[displayNameKey]
            })
        }
        return columnHeaders;
    })

    var koRows = pureComputed(function () {
        var data = paramData();
        var columns = paramColumns();
        var fieldKey = unwrap(paramFieldKey);
        var rows = [];
        for (var i in data) {
            var datum = data[i];
            var cells = []
            var row = {
                entity: data,
                cells: cells
            };
            for (var j in columns) {
                var column = columns[j];
                cells.push(datum[column[fieldKey]] || "");
            }
            rows.push(row);
        }
        return rows;
    });


    return {
        rows: koRows,
        columns: koColumnHeaders,
    }
}

ko.applyBindings(new viewModel({
    data: data,
    columns: columns
}))
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

    <table class="table table-bordered" border="1">
        <thead>
            <tr data-bind="foreach: columns">

                <th data-bind="text: displayName">
                </th>

            </tr>
        </thead>
        <tbody data-bind="foreach: rows">
            <tr>
                <!-- ko foreach: cells -->
                <td class="" data-bind="text: $data"></td>
                <!-- /ko -->
            </tr>
        </tbody>
    </table>

【讨论】:

  • 我试图将您的代码放入 jsfiddle 但它不起作用。这是 jsfiddle:jsfiddle.net/Lme0nwoy/1。你能更新一下吗?
  • 嘿伙计,这是一个淘汰组件,你可以通过使用 来使用它html
  • 我是淘汰赛新手,所以没有使用淘汰赛组件。将不得不看看这是如何工作的。您能否提供一个可行的示例,或者让我知道我需要对上面的 jsfiddle 进行哪些更新才能使其正常工作
  • 你能不能给我一个例子来说明如何让它工作。如果您能更新上面的 jsfiddle 将不胜感激。
【解决方案2】:

我能够使用以下帖子解决此问题: Knockout JS: Get Textbox data from Table under for-each binding

这是我的代码:

 (function() {
var ViewModel = function() {
var self = this;
self.valuesData = ko.observableArray();

self.columns = ko.computed(function() {
  if (self.valuesData().length === 0)
    return [];

  return ValuesData.columns;
});


self.addRow = function() {
  self.valuesData.push(new ValuesData());
};

self.Save = function() {
  alert('Data:')
};

self.removeRow = function(data) {
  self.valuesData.remove(data);
};
}

// Dynamic values.
var ValuesData = function(siid, comment) {
var self = this;

// Add observables dynamically for all relevant columns.
for (var i = 0; i < ValuesData.columns.length; i++) {
  var column = ValuesData.columns[i];
  self[column.Property] = ko.observable(column.InitialValue)
 }
};

// Basic column definition.
ValuesData.columns = [{
  Caption: 'SIID',
  Property: 'SIID',
  InitialValue: undefined
},
{
  Caption: 'Column 1',
  Property: 'Col1',
  InitialValue: undefined
},
{
  Caption: 'Column 2',
  Property: 'Col2',
  InitialValue: 'banana'
},
{
  Caption: 'Comment',
  Property: 'Comment',
  InitialValue: undefined
}
]

vm = new ViewModel()
ko.applyBindings(vm);

// add initial row.
vm.addRow();


})();

这里是html部分:

 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-
 min.js"></script>
  <br><br>
<table>
 <thead>
 <!-- NEW: use ko foreach with 'as' to have an alias for accessing $data. -->
 <tr data-bind="foreach: { data: columns, as: 'column'}">
  <th> <span data-bind="text: column.Caption"></span>
  </th>
 </tr>
</thead>
  <tbody data-bind="foreach: { data: valuesData, as: 'rowData'}">
  <tr data-bind="foreach: { data: $parent.columns, as: 'column' }">
  <!-- NEW: bind to the corresponding property/observable in ValuesData -->
  <td><input type="text" class="form-control textbox" data-bind="textInput: 
 rowData[column.Property]" /> </td>
  </tr>
   <tr>
   <td>
    <input type="button" value="Remove Row" data-bind="click: 
 $parent.removeRow" class="btn btn-danger" />
    </td>
  </tr>
</tbody>



【讨论】:

    猜你喜欢
    • 2012-05-21
    • 2013-03-09
    • 1970-01-01
    • 2023-03-31
    • 2019-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    相关资源
    最近更新 更多