Knockout + Datatables - 更新单元格中的绑定

时间:2013-07-22 00:31:10

标签: knockout.js datatables

我目前正在使用Josh Buckley的数据表绑定Knockout。我正在尝试在数据表中创建“删除行”按钮。我目前在每个按钮上都有一个click data-bind。数据源源连接到一个可观察的数组。当用户单击该按钮时,该对象将从可观察数组中删除,然后该数组将触发更新绑定,随后会更新表视图。这一切都很好,至少我第一次点击按钮。

但是,一旦更新了表,“删除行”按钮上的所有点击绑定都将停止工作。我认为这是因为每次调用更新绑定时都会清除并重建整个表,因此绑定不会应用于新元素。

如何重新绑定每个数据表更新生成的新元素?或者,有没有更好的方法来处理这个?

自定义绑定:

(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);

HTML code:

<table id="membersTable" class="table table-striped table-bordered bootstrap-datatable datatable" data-bind="dataTable: membersTable">
    <thead>
        <tr>
            <th>Name</th>
            <th>Actions</th>
        </tr>
    </thead>   
</table>

查看型号:

var groupViewModel = {  
    groupMembers: ko.observableArray([
        new GroupMember("1", "Abe", true),
        new GroupMember("2", "Bob", false),
        new GroupMember("3", "Bill", false)
    ])
};

groupViewModel.membersTable = ko.computed(function() {
    var self = this;

    var final_array = new Array();
    for(var i = 0; i < self.groupMembers().length; i++)
    {
        var row_array = new Array();
        row_array[0] = self.groupMembers()[i].nameWithLink();
        row_array[1] = self.groupMembers()[i].actions();
        final_array.push(row_array);
    }

    return final_array;
}, groupViewModel);

groupViewModel.removeMember = function(id) {
    var self = this;

    self.groupMembers.remove(function(groupMember) {
        return groupMember.id == id;
    });
};

群组成员对象:

function GroupMember(id, name, isGroupLeader)
{
    var self = this;
    self.id = id;
    self.name = name;
    self.isGroupLeader = ko.observable(isGroupLeader);

    self.link = ko.computed(function() {
        return "/#user/" + self.id;
    }); 

    self.nameWithLink = ko.computed(function() {
        return '<a href="' + self.link() + '">' + self.name + '</a>';
    });

    self.actions = ko.computed(function() {
        return '<a class="btn btn-danger" data-bind="click: function() {removeMember(' + self.id + ')}">' + '<i class="icon-minus-sign"></i>' + '</a>';
    });
}

编辑:

jsfiddle链接:http://jsfiddle.net/zongweil/PLUKv/1/

1 个答案:

答案 0 :(得分:0)

http://jsfiddle.net/PLUKv/4/

我不确定Buckley家伙的数据表绑定,但是你发布的原始小提琴中存在很多问题所以我会触及那些因此你可以看到为什么我发布的解决方案有效并且是一种更好的方法 -

  1. 不要仅为了为数据提供某些功能(例如删除或链接)而创建数组数组。这是不好的做法,你正在为自己设置问题。您可以使用像我放入viewmodel中的通用方法向数据记录添加功能,也可以使用大量其他方法 - 但不要在视图模型中添加HTML。

  2. 您无需在视图模型中预览数据即可添加功能。 Knockout通过在视图中为您提供所需的工具来帮助您,以便您的视图模型不必了解视图。此外,不要将视图模型功能放入您的视图中 - 这是不好的做法(您的HTML中注入了一个函数,那很脏!)

  3. 最后,不要将视图模型功能放入模型中 - 这就是您的视图模型的用途!

  4. 您的视图在渲染时更快更有效 - 让它完成它的工作 -

    <tbody data-bind="foreach: groupMembers">
        <tr>
        <td><a data-bind="click: $parent.gotoPersonLink, text: name" /></td>
        <td><button data-bind="click: $parent.removeMember"><i class="icon-remove" /></button></td>
        </tr>
    </tbody>
    

    为您的视图模型提供提供功能的机会,而无需注入HTML -

    self.removeMember = function (member) {
        self.groupMembers.remove(member);
    };
    
    self.gotoPersonLink = function (member) {
        alert('add your change window logic here');    
    };
    

    您总是可以在模型中添加功能,例如删除成员,但这意味着如果您有1000条记录,则代码运行的次数超过了所需的999次。话虽这么说,如果你必须回到原来的做法,那么祝你好运!如果是这种情况,那就摆脱你对Knockout的依赖,因为你根本就不需要它。