【问题标题】:Using Knockout with Datatables Ajax source将 Knockout 与 Datatables Ajax 源一起使用
【发布时间】:2013-05-09 21:50:13
【问题描述】:

我有一个这样的数据表,并且想让我的数据表行具有可剔除的可观察属性。能够绑定数据的最佳方法是什么:“单击”数据表中的一行。我见过一个数据表敲除绑定,但它似乎不支持 ajax 源。我尝试使用 foreach 和模板绑定创建表并让数据表从 DOM 初始化它的任何想法,但它删除了我拥有的绑定,所以当我现在单击它时它什么也不做。也显得很慢。我想使用 AJAX 或 JS 数组。

         {            
            "bDeferRender" : true,
            "bProcessing" : true,
            "sDom": '<"top"r>t<"bottom"lp><"clear">',
            "oLanguage" : {
            "sLoadingRecords" : "&nbsp;",
                "sProcessing" : processDialog
            },
            "sAjaxSource":'/get_statistics',
            "sAjaxDataProp": 'landing_page_statistics',
            "fnServerParams": function (aoData) {
                aoData.push({"name": "start_date", "value": startDateEl.val()});
                aoData.push({"name": "end_date", "value": endDateEl.val()});
            },
            "aoColumns" : [
                {"mData" : "status", "sWidth": "6%"},
                {"mData" : "name"},
                {"mData" : "url"},
                {"mData" : "pageViews", "sWidth": "15%"},
                {"mData" : "leads", "sWidth": "5%"},
                {"mData" : "convRate", "sWidth": "12%"}
            ],
            "fnRowCallback": function (nRow, aData, iDisplayIndex) {
                renderDataTableRow(nRow, aData, iDisplayIndex);
            },
            "fnFooterCallback" : function (nFoot, aData, iStart, iEnd, aiDisplay) {
               renderDataTableTotalsRow(nFoot, aData, iStart, iEnd, aiDisplay);
            },
            "fnDrawCallback": function( oSettings ) {
                // status tooltips
                $('.lp-status').tooltip();
            }
        }

【问题讨论】:

    标签: javascript knockout.js jquery-datatables


    【解决方案1】:

    我不确定我是否明白你的问题的重点,如果我这样做了,我的回答就像是在作弊,只是指向相关来源。无论如何,就这样吧。

    您的第一个选项是手动使用load and save AJAX 数据进出您的视图模型。 The related tutorial 在解释事情方面做得相当不错。加载归结为:

    // Load initial state from server, convert it to Task instances, then populate self.tasks
    $.getJSON("/tasks", function(allData) {
        var mappedTasks = $.map(allData, function(item) { return new Task(item) });
        self.tasks(mappedTasks);
    }); 
    

    将其保存到您的服务如下所示:

    self.save = function() {
        $.ajax("/tasks", {
            data: ko.toJSON({ tasks: self.tasks }),
            type: "post", contentType: "application/json",
            success: function(result) { alert(result) }
        });
    };
    

    一个相关的第二个选项是使用mapping plugin以基于约定的方式保存/加载您的ViewModel。不过,您仍然需要一些布线来与服务器通信。

    对于 View 部分,在这两种情况下,我认为您已经有了正确的方法:在 tbody 上使用 foreach binding 并为每个 ViewModel 构造一行。

    同样,这是一个相当模糊/广泛的答案,部分原因是您的问题相当广泛。希望对您有所帮助。

    【讨论】:

    • 抱歉,这个问题很笼统,但我遇到的大部分问题是如何将这些方法与 datatables.net jquery 插件结合起来,特别是 datatables.net 的 AJAX 源实现
    • 啊,我很抱歉。我不知何故错过了你问题中的那些标签。我可能会删除我的答案(或者可能会让其他人看到,即使它对您没有用处)。我没有使用 datatables.net 的经验,因此无法对此发表评论。
    【解决方案2】:

    这是这样做的方法...我已经制作了一个jsfiddle 显示这个:

    为了让它工作,我必须在原始的淘汰赛 foreach 绑定定义中添加两个回调方法。我目前正在尝试将这些事件纳入最新版本的淘汰赛。我需要添加一个 beforeRenderAll 和 afterRenderAll 回调来销毁数据表并在敲除 foreach 绑定添加 html 后重新初始化数据表。这就像一个魅力展示这个的 JSFiddle 有一个完全可编辑的 jquery 数据表,通过敲除绑定到 ViewModel。

    使用 Knockout,您将不会使用数据表的 ajax 实现。您将使用已定义 html 的标准实现。让 Knockout 通过 ajax 加载数据并将其分配给可观察数组来处理 html。然后下面的自定义 foreach 绑定将销毁数据表,让 knockout 以默认的敲除 foreach 方式处理 html,然后绑定将重新初始化数据表。

    var viewmodel = new function(){
       var self = this;
       this.Objects = ko.mapping.fromJS([]);
       this.GetObjects = function(){
           $.get('your api url here', function(data){
               ko.mapping.fromJS(
                   data,
                   {
                       key: function(o){ return ko.utils.unwrapObservable(o.Id); },
                       create: function(options){ return new YourObjectViewModel(options.data); }
                   },
                   that.Objects
               ); 
           });
       };
    };
    
    //Or if you do not need to map to a viewmodel simply just...
    $.get('your api url here', function(data){
        viewmodel.Options(data);
    });
    

    下面是自定义数据表绑定...

    ko.bindingHandlers.DataTablesForEach = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                 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().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 };
        }
    };
    

    【讨论】:

    • 这不能回答问题。在 DataTables 中使用 Ajax 模式的全部意义在于,它会在您需要时自动发出 ajax 请求(搜索值更改、排序列更改、页面更改等)。
    猜你喜欢
    • 2017-02-20
    • 2013-03-24
    • 1970-01-01
    • 2015-11-23
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    相关资源
    最近更新 更多