jQuery DataTables 和 Knockout 未正确绑定

jQuery DataTables and Knockout not binding properly

本文关键字:绑定 Knockout DataTables jQuery      更新时间:2023-09-26

我有一个Ajax调用,它返回了一个"团队"。球队由队名、联赛名和具有姓名、位置和队名的足球运动员列表组成。Ajax 调用正确返回了团队 JSON,我将直接在团队上对属性进行淘汰绑定。但是,我想将jQuery DataTable绑定到玩家列表,但这样做没有成功。我可以判断正在进行数据表调用,因为我可以看到一些数据表控件,如"上一页 1 下一个",但表中没有数据。如果有帮助的话,我可以将我所拥有的内容部署到一个公开可见的站点。谢谢!

  • jQuery:版本 2.1.1
  • 淘汰赛:版本 3.2.0
  • 数据表:版本1.10.4

目录

<table id="playerList">
    <thead>
        <tr>
            <th>Player Name <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span></th>
            <th>Position <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span></th>
            <th>Team <span class="glyphicon glyphicon-sort-by-alphabet" aria-hidden="true"></span></th>
        </tr>
    </thead>
    <!--<tbody data-bind='foreach: PlayerList'>-->
    <tbody>
        <tr>
            <td data-bind="text: $data.PlayerList.Name"></td>
            <td data-bind="text: $data.PlayerList.SelectedPosition"></td>
            <td data-bind="text: $data.PlayerList.TeamName"></td>
        </tr>
    </tbody>
</table>

控制器 Javascript

$('.retrieveTeam').click(function () {
        _getData('RetrieveTeam', JSON.stringify({ TeamKey: $(this).data("teamkey") }));
    });
function _getData(url, postdata) {
    var request = $.ajax({
        url: url,
        type: 'POST',
        data: postdata,
        datatype: "json",
        contentType: "application/json"
    });
    request.done(_requestDone);
    request.fail(_failedRequest)
}
function _requestDone(result)
{
    _bindTeam(result);
    my.Views.TeamView.showTeamInfo();
}
function _bindTeam(data) {
    if (!viewModel) {
        viewModel = ko.mapping.fromJS(data, {}, this);
        ko.applyBindings(viewModel);
        my.Views.TeamView.applyDataTable('#playerList');
    } else {
        ko.mapping.fromJS(data, viewModel);
    }        
}

查看 Javascript

var applyDataTable = function applyDataTable(element) {
    $(element).DataTable(
        {
            responsive: true,
            bFilter: false,
            bInfo: false,
            bLengthChange: false
        });
}

这是我是如何做到的...这个小提琴使用自定义的DataTablesForEach绑定,还包括一个敲除叉...我已经在 github 上创建了一个带有淘汰仓库的拉取请求。如果此解决方案对您有所帮助,请在我的拉取请求上发表评论,以将其合并到淘汰赛 3.4 中。谢谢!

斯菲德尔

拉取请求 #1856 GitHub 上的挖空/挖空存储库

ko.bindingHandlers.DataTablesForEach = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
             var nodes = Array.prototype.slice.call(element.childNodes, 0);
            ko.utils.arrayForEach(nodes, function (node) {
                if (node && node.nodeType !== 1) {
                    node.parentNode.removeChild(node);
                }
            });
            return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
        },
        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var value = ko.unwrap(valueAccessor()),
            key = "DataTablesForEach_Initialized";
            var newValue = function () {
                return {
                    data: value.data || value,
                    beforeRenderAll: function (el, index, data) {
                        if (ko.utils.domData.get(element, key)) {
                            $(element).closest('table').DataTable().clear();
                            $(element).closest('table').DataTable().destroy();
                        }
                    },
                    afterRenderAll: function (el, index, data) {
                        $(element).closest('table').DataTable(value.options);
                    }
                };
            };
            ko.bindingHandlers.foreach.update(element, newValue, allBindingsAccessor, viewModel, bindingContext);
            //if we have not previously marked this as initialized and there is currently items in the array, then cache on the element that it has been initialized
            if (!ko.utils.domData.get(element, key) && (value.data || value.length)) {
                ko.utils.domData.set(element, key, true);
            }
            return { controlsDescendantBindings: true };
        }
    };