API 外掛程式開發

DataTable 的 API 提供大量的函式,可用於操作表格並從中收集資料。您需要的大多數函式都是內建的,但您也可能會發現建立一個外掛程式 API 函式來擴充內建功能會很有用。此頁面討論如何為 DataTables 建立外掛程式 API 函式。

在詳細介紹如何建立外掛程式函式之前,先考慮可能建立哪些類型的外掛程式可能會很有用

  • 使用標準 API 進行常見操作的捷徑(將多個呼叫縮短為單個函式)
  • 資料摘要函式(總和、平均值、標準差等)
  • 用於功能外掛程式的表格操作。

DataTables API

在為 DataTables 建立新的 API 函式之前,重要的是要了解API 的基本原理,尤其是鏈式操作的概念,即函式會傳回自己的實例,以便可以立即對第一個函式的結果呼叫其他函式,以及結果集。

DataTables API 實例是類似陣列的,因為它看起來很像 Javascript 陣列,並且具有許多相同的函式和屬性 (例如.length) - 該陣列的內容是「結果集」。值得注意的是,API 在技術上不是陣列,只是非常像它,就像 jQuery 是類似陣列的,您可以使用陣列語法來存取節點一樣。

實例的結果集可以是空陣列、列、欄或儲存格索引的陣列、資料物件或任何其他內容。所有類型的資料都將在結果集中遇到,而包含的內容將很大程度上取決於您自己的函式的性質。

執行範圍

外掛程式 API 函式是在該 API 實例的範圍內執行的 - 例如,this.rows() 將呼叫rows() 函式。因此,除了您希望執行的任何 Javascript 資料和 DOM 操作之外,您自己的函式還可以存取完整的內建 API 集。

除此之外,API 實例應操作的表格保存在 this.context 參數中。context 參數是 DataTables 設定物件的陣列(每個表格都是唯一的)- 它必須是一個陣列,因為 API 可以識別多個表格,並且該函式應對 context 引用的所有表格執行操作。

註冊新函式

可以使用 DataTable.Api.register() 靜態函式註冊新的 API 函式。它採用兩個參數,且沒有傳回值

  • 輸入參數
    • 函式名稱
    • 函式

函式名稱是完整的鏈式表達式)。例如,若要新增 rows().sum() 函式,您可以使用該完整的字串 (rows().sum())。sum() 函式僅適用於 rows() 函式的結果 - 這將由 DataTables API 處理器自動新增。也可以將 sum() 視為「頂層函式」,它將適用於任何 API 實例,無論其鏈式操作如何。

函式是描述外掛程式邏輯的 function。如上所述,它是在 API 實例的範圍內執行的。此外,它可以傳回任何值(包括用於鏈式操作的實例,如果沒有其他傳回值),並且將接受您為函式所需的任何參數。

範例

讓我們考慮兩個範例來說明這些重點。第一個 sum() 將是一個頂層函式,它將簡單地將結果集中的資料求和並傳回。第二個將附加到 rows() 函式,並提供向選定列新增類別的功能。它將傳回實例以進行鏈式操作。

sum()

sum() 函式實際上非常簡單 - 我們循環遍歷結果集中的資料,並簡單地將它們全部加在一起並傳回值。最終結果是,當結果集中有數值資料時,我們可以使用一個函式來對數值資料求和 - 例如,從呼叫 columns().data()

DataTable.Api.register( 'sum()', function () {
    var sum = 0;

    for ( var i=0, ien=this.length ; i<ien ; i++ ) {
        sum += this[i];
    }

    return sum;
} );

範例呼叫

  • table.column( 2 ).data().sum();
  • `table.cells( '.selected', 3 ).data().sum();

rows().addClass()

這個範例比較複雜,因為我們需要考慮 API 的多表格性質。需要發生的是,我們循環遍歷 API 中的每個 context(即每個表格),並且對於每個表格,也循環遍歷該表格中的列,並在需要時新增類別。

這是最完整的程式碼形式

DataTable.Api.register( 'rows().addClass()', function ( klass ) {
    var context = this.context;

    for ( var i=0, ien=this.length ; i<ien ; i++ ) {
        var innerApi = new DataTable.Api( context[i] );

        for ( var j=0, jen=this[i].length ; j<jen ; j++ ) {
            var node = innerApi.row( this[i][j] ).node();
            $(node).addClass( klass );
        }
    }

    return this;
} );

請注意,rows() 會使用陣列的陣列來填入結果集!每個表格一個內部陣列,每個內部陣列都包含該表格的索引。在上面的程式碼中,這表示 this.context.length === this.length(即,每個表格的結果集中都有一個項目)。

由於以這種形式循環遍歷多個表格在 API 中很常見,因此 DataTables 提供了一個 iterator 函式來簡化它。iterator 將在內部處理雙 for 循環(和許多其他循環類型),並向閉包函式提供有關循環的資訊。因此,上面的程式碼可以簡化為

DataTable.Api.register( 'rows().addClass()', function ( klass ) {
    return this.iterator( 'row', function ( context, index ) {
        var node = new DataTable.Api( context ).row( index ).node();
        $(node).addClass( klass );
    } );
} );

DataTables 1.10.3 開始,這可以進一步簡化,因為 iterator 的回呼函式是在 API 實例的範圍內執行的,該實例的 context 中僅包含相關表格

DataTable.Api.register( 'rows().addClass()', function ( klass ) {
    return this.iterator( 'row', function ( context, index ) {
        var node = this.row( index ).node();
        $(node).addClass( klass );
    } );
} );