1

このようなデータ テーブルがあり、データ テーブルの行にノックアウトの観測可能なプロパティを持たせたいと考えています。データテーブルの行を「クリック」してデータバインドできるようにするための最良の方法は何ですか。datatables ノックアウト バインディングを見たことがありますが、ajax ソースをサポートしていないようです。foreach および template バインディングを使用してテーブルを作成し、datatables で DOM からテーブルを初期化しようとしたアイデアはありますが、バインディングが削除されるため、クリックしても何もしません。また、遅いようです。AJAX または JS Array を使用したいと考えています。

         {            
            "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

これはそれを行う方法です...私はこれを示すjsfiddleを作成しました:

これを機能させるには、元のノックアウト foreach バインディング定義に 2 つのコールバック メソッドを追加する必要がありました。現在、これらのイベントを最新バージョンのノックアウトに取り込もうとしています。beforeRenderAll および afterRenderAll コールバックを追加して、データテーブルを破棄し、ノックアウト foreach バインディングが html を追加した後にデータテーブルを再初期化する必要がありました。これは魅力のように機能します。これを示す JSFiddle には、ノックアウトによって ViewModel にバインドされた完全に編集可能な jquery データテーブルがあります。

Knockout では、データテーブルの ajax 実装を使用しません。html が既に定義されている標準の実装を使用します。Ajax を介してデータをロードし、それを監視可能な配列に割り当てることで、Knockout が html を処理できるようにします。次に、以下のカスタム foreach バインディングはデータテーブルを破棄し、ノックアウトがデフォルトのノックアウト 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 に答える
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) }
    });
};

関連する2 番目のオプションは、マッピング プラグインを使用して、ViewModel を規約に基づいた方法で保存/ロードすることです。ただし、サーバーと通信するにはまだ配線が必要です。

ビュー パーツについては、どちらの場合も、すでに正しいアプローチをとっていると思いますtbody

繰り返しますが、これはかなり漠然とした/大まかな答えです。これは、質問がかなり広いためです。それが役に立てば幸い。

于 2013-05-10T09:26:42.690 に答える