KnockoutJS与jQuery数据表和绑定插件,行单击传递整个数组而不是单个模型

KnockoutJS with jQuery Datatables and the binding plugin, row click passing the whole array instead of single model

本文关键字:数组 模型 单个 单击 数据表 jQuery 绑定 插件 KnockoutJS      更新时间:2023-09-26

我正在使用这个插件 http://www.joshbuckley.co.uk/2011/07/knockout-js-datatable-bindings/处理数据表/KO 绑定。这是JS代码:

function ProductViewModel() {
  // Init.
  var self = this;
  self.products = ko.observableArray();
  self.singleProduct = ko.observable();
  var mappedProducts;
  // At first load i'm loading data.
  $.getJSON("/admin/test", function(allData) {
    mappedProducts = $.map(allData, function(item) { 
      var p = new Product(item);
      // I'm adding a new property to my model, to handle row level actions.
      // I'm not sure this is a good practice.
      p.edit = "<button data-bind='click: $root.edit'><i class='icon-pencil'></i></button>";
      return p;
    });
    self.products(mappedProducts);
  });
  // Here i'm using the basic switch pattern, as from KO tutorials.
  self.edit = function(product) {
    console.log(product); // <--- Prints the whole self.products() array
    self.singleProduct(product);
    self.products(null);
  }
  self.list = function() {
    self.products(mappedProducts);
    self.singleProduct(null);
  }
}
// My model.
function Product(item) {
  this.name = ko.observable(item.name);
  this.dealer = ko.observable(item.dealer);
  this.cost = ko.observable(item.cost);
  this.price = ko.observable(item.price);
  this.picture = ko.observable();
}

这是我的标记:

<table id="products-table" class="table table-striped table-bordered table-hover"
             data-bind="dataTable: {data: $parent.products, options: {aoColumns: [
        { bSortable: false, mDataProp: null, sDefaultContent: '' },
        {mData: 'name'}, 
        {mData: 'dealer'},
        {mData: 'cost'},
        {mData: 'price'}, 
        { bSortable: false, mData: 'edit' }
      ]}}">
        <thead>
          <tr>
            <th>Pic</th>
            <th>Name</th>
            <th>Dealer</th>
            <th>Cost</th>
            <th>Price</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody></tbody>
      </table>

我能够在列表和编辑视图之间虚拟切换,绑定似乎得到了正确处理。

问题:在编辑处理程序中,我希望收到单个模型作为参数;不过我正在接收整个集合,所以我无法识别要编辑的模型。

还有一件事:我完全不确定这是在行上绑定事件的好做法,所以任何建议将不胜感激!

好吧,我想我自己得到了它,并且在偷看插件源代码后原因很清楚。

从插件源:

(function($){
    ko.bindingHandlers.dataTable = {
        init: function(element, valueAccessor){
            var binding = ko.utils.unwrapObservable(valueAccessor());
            // If the binding is an object with an options field,
            // initialise the dataTable with those options. 
            if(binding.options){
                $(element).dataTable(binding.options);
            }
        },
        update: function(element, valueAccessor){
            var binding = ko.utils.unwrapObservable(valueAccessor());
            // If the binding isn't an object, turn it into one. 
            if(!binding.data){
                binding = { data: valueAccessor() }
            }
            // Clear table
            $(element).dataTable().fnClearTable();
            // Rebuild table from data source specified in binding
            $(element).dataTable().fnAddData(binding.data());
        }
    };
})(jQuery);

基本上,对于每个更新,操作表都会被清理并使用可观察数组重新构建,这应该提供绑定功能。

KO试图做的是,在每次本机点击:绑定中,将上下文数据(即整个数组)传递给适当的处理程序。