2017-12-20 21 views
0

DataTableの更新に役立つcustom KO bindingHandlerをセットアップしました。Knockout BindingHandlerを使用してJQuery.Datatablesを公開するを選択しますか?

データを取得する方法については、JQuery.DataTable.Selectのdocumentationにハンドルが必要です。

var table = $('#myTable').DataTable(); 

table.rows({ selected: true }).data(); 

しかし、私のko.bindingHandlerはので、私は$('#myTable').DataTable()のハンドルを持っていない私のCSHTMLファイルへのDataTableの設定を移動します。

私のViewModelでDataTable関数を使用できるようにするにはどうすればよいですか? $( '#myTable')をdataTableとしてキャストするためにJQueryを使用できるかもしれないと思っていましたが、そのような運がないのです。

.cshtml:

<table id="myTable"> 
    <thead> 
    <tr> 
     <th>Title</th> 
    </thead> 
    <tbody data-bind="dataTablesForEach: {data: trainingSearchResults, dataTableOptions: { 
       select: {items: 'row', style: 'os'}, 
       searching: false, 
       info: false, 
       paging: false 
       }"> 
     <tr> 
     <td data-bind="text: title"></td> 
     </tr> 
    </tbody> 
</table> 

カスタムバインディング:

import * as ko from "knockout" 
import * as $ from "jquery"; 

export class KnockoutExtensions { 
    // Constructor 
    constructor() { 
     ko.bindingHandlers.dataTablesForEach = { 
      page: 0, 
      init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
       var options = ko.unwrap(valueAccessor()); 
       ko.unwrap(options.data); 
       if (options.dataTableOptions.paging) { 
        valueAccessor().data.subscribe(function (changes) { 
         var table = $(element).closest('table').DataTable(); 
         ko.bindingHandlers.dataTablesForEach.page = table.page(); 
         table.destroy(); 
        }, null, 'arrayChange'); 
       } 
       var nodes = Array.prototype.slice.call(element.childNodes, 0); 
       ko.utils.arrayForEach(nodes, function (node: Node) { 
        if (node && node.nodeType !== 1) { 
         node.parentNode.removeChild(node); 
        } 
       }); 
       return ko.bindingHandlers.foreach.init(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext); 
      }, 
      update: function (element, valueAccessor, allBindings, viewModel, bindingContext) { 
       var options = ko.unwrap(valueAccessor()), 
        key = 'DataTablesForEach_Initialized'; 
       ko.unwrap(options.data); 
       var table; 
       if (!options.dataTableOptions.paging) { 
        table = $(element).closest('table').DataTable(); 
        table.destroy(); 
       } 
       ko.bindingHandlers.foreach.update(element, valueAccessor, allBindings, viewModel, bindingContext); 
       table = $(element).closest('table').DataTable(options.dataTableOptions); 
       if (options.dataTableOptions.paging) { 
        if (table.page.info().pages - ko.bindingHandlers.dataTablesForEach.page == 0) 
         table.page(--ko.bindingHandlers.dataTablesForEach.page).draw(false); 
        else 
         table.page(ko.bindingHandlers.dataTablesForEach.page).draw(false); 
       } 
       if (!ko.utils.domData.get(element, key) && (options.data || options.length)) 
        ko.utils.domData.set(element, key, true); 
       return { controlsDescendantBindings: true }; 
      } 
     }; 
    } 
} 

答えて

0

ちょうど私のViewModelから再初期化を呼び出そうとしている間:

var table = $("#trainingSearchResultsTable").DataTable({ 
    select: { items: 'row', style: 'os' }, 
    searching: false, 
    info: false, 
    paging: false 
}); 

は私ですエラーWarning: Cannot reinitialise

それはanswerに私を導く:

このエラーは、選択したノード のためのDataTableインスタンスが既に初期化されたときのDataTable コンストラクタオブジェクトにオプションを渡すことによってトリガーされます。

オブジェクトインスタンス検索

APIを操作するため データテーブルへの参照を取得しようとすると、このエラーが頻繁に発生する可能性があります。たとえば、 関数を使用して、 によってDataTableインスタンスを作成しようとすると、作成時にオプションが渡されます。次に、 がすでに初期化されているテーブルでこの関数を呼び出し、 このエラーが発生するように変更します。

このような場合、静的メソッド$ .fn.dataTable.isDataTable() を使用することをお勧めします。テーブルが既にDataTableのか でない場合、これはチェックするために使用することができます。

if ($.fn.dataTable.isDataTable('#example')) { 
    table = $('#example').DataTable(); 
} 
else { 
    table = $('#example').DataTable({ 
     paging: false 
    }); 
} 
関連する問題