KnockoutJS Grid 添加项目

KnockoutJS Grid to add items

我目前有一个表单可以让用户将项目添加到提交中,因为我是 KnockoutJS 的新手,所以我刚刚制作了这个表单来接受一个产品进行提交

<script type="text/html" id="page4-template">
<h4>Strain Information : </h4>
<table>
    <tr>
        <td class="firstCol">Stock number : </td>
        <td><span id="SummaryP1_StockNum" data-bind="text: stockNumber"></span></td>
    </tr>
    <tr>
        <td class="firstCol">Product Needed : </td>
        <td>
            <span id="SummaryP1_pdtNeeded" data-bind="text: pdtNeeded"></span>
            <span data-bind="visible: pdtNeeded() == 'Other'">
                <span id="SummaryP1_pdtNeededPleaseExplain" data-bind="text: pdtNeededPleaseExplain"></span>
            </span>
        </td>
    </tr>
    <tr>
        <td class="firstCol">Requested Ship Date : </td>
        <td><span id="SummaryP1_RequestedShipDate" data-bind="text: requestedShipDate"></span></td>
    </tr>
    <tr>
        <td class="firstCol">Aditional Information : </td>
        <td><span id="SummaryP1_AdditionalInformation" data-bind="text: additionalInformation"></span></td>
    </tr>

</table>
<hr>
</script>

如果我需要制作此表单以允许用户动态地向提交添加更多项目,我应该在此处使用什么,我有点困惑,因为它们是动态引导、Overservable 数组等​​等。任何人都可以建议我可以做些什么来简单地允许用户动态添加项目。

您确实希望使用 observableArray 来存储多个项目。然后你用 foreach 绑定循环遍历这个数组,并在你的视图模型上添加一个方法来将新项目推送到这个数组。

像这样:

vm.row = ko.observableArray();

vm.addRow = function () {
    vm.row.push({
        stockNumber: ko.observable(1),
        pdtNeeded: ko.observable('Other'),
        pdtNeededPleaseExplain: ko.observable('Hello'),
        requestedShipDate: ko.observable(),
        additionalInformation: ko.observable()
    })
}

Fiddle: https://jsfiddle.net/thebluenile/2q8tbp5n/

为了更好地衡量,我还添加了一个示例,说明如何删除行。

我建议三个步骤:

第一步是将绑定到 table 元素的所有可观察属性收集到一个对象中:

createRowItem = function(data) {
    return {
        additionalInformation = ko.observable(data.additionalInformation),
        pdtNeeded = ko.observable(data.pdtNeeded),
        pdtNeededPleaseExplain = ko.obsevable(data.pdtNeededPleaseExplain),
        requestedShipDate = ko.observable(data.requestedShipDate),
        stockNumber = ko.observable(data.stockNumber),
    }
};

您将获得一个新的实例 rowItem...

var newRowItem = createRowItem(data);

第二步是在您现有的视图模型中创建一个 observableArray (documentation):

self.rowItems = ko.observableArray([]);

要用 rowItem 个实例的集合填充该数组,您 可以 调用 self.rowItems.push(newRowItem) (documentation),但获取它的效率更高对内部数组的引用(,observableArray 正在监视的原始数组),将新实例添加到其中,然后告诉 observableArray 它的数据已更新。 [这种效率的原因与 Knockout 内部工作的方式有关,并跟踪突变。]

我的建议是在视图模型的 public 函数中执行此操作:

self.addRowItem = function(newRowItem) {
    var arr = ko.unwrap(self.rowItems);  // obtain the underlying array
    arr.push(newRowItem);  // add the new object to the underlying array
    self.rowItems.valueHasMutated();  // tell Knockout that the underlying array has been modified
};

最后一步是将 <tr> 元素包装在 foreach 绑定中 (documentation):

<script type="text/html" id="page4-template">
<h4>Strain Information : </h4>
<table data-bind="foreach: rowItems">
    <tr>
        <td class="firstCol">Stock number : </td>
        <td><span id="SummaryP1_StockNum" data-bind="text: stockNumber"></span></td>
    </tr>
    ...
</table>