1

我有一个像这样的数据表,并且想让我的数据表行具有可剔除的可观察属性。能够绑定数据的最佳方法是什么:“单击”数据表中的一行。我见过一个数据表敲除绑定,但它似乎不支持 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();
            }
        }
4

2 回答 2

0

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

您的第一个选择是手动使用加载和保存AJAX 数据到您的视图模型和从视图模型中保存。相关教程在解释事情方面做得相当不错。加载归结为:

// 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) }
    });
};

相关的第二个选项是使用映射插件以基于约定的方式保存/加载您的 ViewModel。不过,您仍然需要一些接线才能与服务器通信。

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

同样,这是一个非常模糊/广泛的答案,部分原因是您的问题相当广泛。希望能帮助到你。

于 2013-05-10T09:26:42.690 回答
0

这就是这样做的方法......我做了一个jsfiddle来展示这个:

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

使用 Knockout,您将不会使用数据表的 ajax 实现。您将使用已定义 html 的标准实现。让 Knockout 通过 ajax 加载数据并将其分配给可观察数组来处理 html。然后下面的自定义 foreach 绑定将销毁数据表,让 Knockout 以默认的 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 };
    }
};
于 2015-09-22T17:55:13.310 回答