1

嗨,我正在尝试使用 KnockoutJs 在表上进行多行删除。当我尝试在桌子上使用时,我不知道为什么我的代码不起作用。我已经在 ul 上尝试过这个,它工作得很好。

下面是我的代码。需要帮助提前谢谢:(

HTML:

<table class="pure-table" id="tbl_ordered_products">
        <thead>
            <tr>
                <th><input type="checkbox" id="chkAllProducts" /></th>
                <th>Product Code</th>
                <th>Product Name</th>
                <th>Price</th>
                <th>Quantity</th>
                <th>Discount Rate</th>
                <th>Stock Balance</th>
                <th>Total Discount</th>
                <th>Orig. Price</th>
                <th>Total</th> 
            </tr>
        </thead>
        <tbody data-bind="foreach: orderedProducts">
            <tr>
                <td><input type="checkbox" id="chkAllProducts" data-bind="value: $data, checked: $parent.selectedOrderedProducts"/></td>
                <td data-bind="text: product_code"></td>
                <td data-bind="text: name"></td>
                <td data-bind="text: price"></td> 
                <td><input data-bind="value: quantity" /></td>
                <td><input data-bind="value: discount" /></td>
                <td data-bind="text: balance"></td>
                <td data-bind="text: total_discount"></td>
                <td data-bind="text: original_price"></td>
                <td data-bind="text: total_price"></td>
            </tr>    
        </tbody>
    </table>

<input type="button" value="Remove Selected" data-bind="click: deleteSelectedProducts" />

我的 JS:

function Product(id, product_number, name, price, quantity, discount, balance) {
var self = this;
self.id = ko.observable(id);
self.product_code = ko.observable(product_number);
self.name = ko.observable(name);
self.price = ko.observable(price.toFixed(2));
self.quantity = ko.observable(quantity);
self.discount = ko.observable(discount);
self.balance = ko.observable(balance);
}
function OrdersViewModel() {
var self = this;

self.customerCode = ko.observable();
self.full_name = ko.observable();
self.complete_address = ko.observable();
self.birthday = ko.observable();
self.email = ko.observable();
self.contact = ko.observable();

self.orderedProducts = ko.observableArray();
self.selectedOrderedProducts = ko.observableArray();

self.deleteSelectedProducts = function () {
    alert(self.selectedOrderedProducts.length);
    self.orderedProducts.removeAll(self.selectedOrderedProducts());
    self.selectedOrderedProducts.removeAll();
}
4

2 回答 2

2

看起来您对 Knockout 在这里的工作方式有些困惑。

比较一下:

<table class="pure-table" id="tbl_ordered_products">
    <thead>
        <tr>
            <th>
                <input type="checkbox" id="chkAllProducts" data-bind="click: toggleAllProducts" />
            </th>
            <th><label for="chkAllProducts">Product Name</label></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: orderedProducts">
        <tr>
            <td>
                <input type="checkbox" data-bind="checked: isSelected, attr: {id: htmlId}" />
            </td>
            <td><label data-bind="text: name, attr: {for: htmlId}"></label></td>
        </tr>
    </tbody>
</table>
<input type="button" value="Remove Selected" data-bind="click: deleteSelectedProducts" />

function Product(id, name) {
    var self = this;
    self.htmlId = "product_" + id;
    self.id = ko.observable(id);
    self.name = ko.observable(name);
    self.isSelected = ko.observable(false);
}

function OrdersViewModel(products) {
    var self = this,
        productObjects = ko.utils.arrayMap(products, function (product) {
            return new Product(product.id, product.name);
        });

    self.orderedProducts = ko.observableArray(productObjects);

    self.selectedOrderedProducts = ko.computed(function () {
        return ko.utils.arrayFilter(self.orderedProducts(), function (product) {
            return product.isSelected();
        });
    });
    self.toggleAllProducts = function (vm, e) {
        var checkboxState = e.target.checked;
        ko.utils.arrayForEach(self.orderedProducts(), function (product) {
            product.isSelected(checkboxState);  
        });
        return true;
    };
    self.deleteSelectedProducts = function () {
        self.orderedProducts.removeAll(self.selectedOrderedProducts());
    };
}
  • 在您的方法中,您对产品没有isSelected可观察性,但这是拥有工作视图模型的关键。
  • 另一方面,您不需要第二组选定的产品。“选定产品”是您的产品的子集,可以可靠地动态计算。这意味着:使用计算的 observable。ko.utils.arrayFilter()在这里很有帮助。
  • 您的复选框不得具有值绑定。他们从上下文中“知道”他们所在的位置,给他们一个值绑定会破坏事情。(无论如何,您将直接从您的视图模型中为后续的 Ajax 请求组合数据——而不是从您的视图中。复选框值是无关紧要的。)
  • 您缺少“全部切换”功能,所以我做了一个。
  • 外观变化,但对用户体验至关重要:如果您有复选框,则必须有连接的标签。
  • 比较http://jsfiddle.net/SBzYj/
于 2013-10-20T09:37:17.103 回答
2

敲除checked绑定不起作用,什么时候valueobject. isCheckedProduct对象 中使用额外的 pbservable 属性

function Product(id, product_number, name, price, quantity, discount, balance) {
   var self = this;
   self.isChecked = ko.observable(false);
   self.id = ko.observable(id);
   self.product_code = ko.observable(product_number);
   // ...
}  

删除行

self.deleteSelectedProducts = function () {
    var productToRemove = [];
    ko.utils.arrayForEach(self.orderedProducts(), function(product){
       if (product.isChecked()) 
       {
           productToRemove.push(product)
       }
    })
    self.orderedProducts.removeAll(productToRemove)
}  

JSFiddle 演示

于 2013-10-20T09:43:14.443 回答