2015-06-06 25 views
0

我已配置selectize.js以從html數據屬性收集配置選項。我的配置類型之一是能夠指定一個js函數來調用自定義數據加載(在簡單的ajax加載之外)。代碼運行良好,直到我運行一個異步的自定義函數。使用異步方法時,selectize.js加載回調在數據加載之前返回。我一直在努力尋找一種方法將selectize.js load()回調傳遞給自定義加載函數。Selectize.js將回調傳遞加載到自定義函數

這裏是配置爲運行「loadStates()」函數來獲取數據對於該特定選擇元素的選擇元件:

<select 
    id="state" 
    class="selectize" 
    data-load-type="callback" 
    data-load-callback="loadStates" 
> 

這裏是「loadStates()」將被調用的函數。我爲這個例子保持簡單,但理想情況下,這可以是任何類型的方法,包括異步方法。

<script> 
    function loadStates(searchQuery) { 
     return { 
      "states": [ 
       { 
        "id": 1, 
        "abbr": "AK", 
        "description": "Alaska" 
       }, 
       { 
        "id": 2, 
        "abbr": "CA", 
        "description": "California" 
       }, 
       { 
        "id": 3, 
        "abbr": "OR", 
        "description": "Oregon" 
       }, 
       { 
        "id": 4, 
        "abbr": "WA", 
        "description": "Washington" 
       } 
      ] 
     }; 
    } 
</script> 

最後,這裏是我的匿名函數被傳遞給selectize.js加載方法。

// Get custom load function from select element data attribute 
var loadCallback = $(this).attr('data-load-callback'); 

// The selectize.js load option needs an anonymous function with two 
// arguments, query and callback. This function should return the data. 
var _load = function(query, callback) { 

    // Call the custom load function 
    callback(window[loadCallback](query)); 
}; 

// Pass the _load configuration to selectize 
$(this).selectize({load: _load}); 

這一切都適用於簡單的loadStates()函數。但是,只要我添加了一些異步,selectize.js load()回調會很快返回。

什麼心中已經試過:

我試圖發送負載()回調到自定義函數是這樣的:

// ... 

// Call the custom load function 
window[loadCallback](query, callback); 

// ... 

function loadStates(searchQuery, callback) { 
    callback( 
     // ... json data here 
    ); 
} 

但是,不返回任何數據。

更新 - 使用@thewildpendulum溶液:

所以有此load選項與selectize,這是不同的,則負載()API方法。但是,它們的工作方式都相同(希望返回數據),因此對於此問題的目的沒有真正的區別。

我在上面稍微簡化了一下我的代碼,我會做一個說明,不要在將來這樣做。我還有兩個可選參數,用戶可以指定將這些數據分割爲更小的選項,指定返回數據中的一個鍵和/或記錄限制。我想我有一個同事提供的很好的解決方案。如果有更好的方法,我將不勝感激。

新的回調對象的建議,增加了兩個負載參數性能

// callbacks object for custom user provided data methods 
var callbacks = { 
    loadKey: null, 
    loadLimit: 0, 
    loadStates: function (query, selectizeCallback) { 
     var data = { 
     "states": [ 
      { 
      "id": 1, 
      "abbr": "AK", 
      "description": "Alaska" 
      }, 
      { 
       "id": 2, 
       "abbr": "CA", 
       "description": "California" 
      }, 
      { 
       "id": 3, 
       "abbr": "OR", 
       "description": "Oregon" 
      }, 
      { 
       "id": 4, 
       "abbr": "WA", 
       "description": "Washington" 
      } 
     ] 
     }; 
     if (null !== this.loadKey) { 
     selectizeCallback(data[this.loadKey].slice(0, this.loadLimit)); 
     } 
     else { 
     selectizeCallback(data.slice(0, this.loadLimit)); 
     } 
    } 
    } 

建設selectize負載選項與用戶回調對象和自定義數據切片

// Set load parameters (gather these values from html data attr earlier) 
callbacks.loadKey = loadKey; 
callbacks.loadLimit = loadLimit; 

// Build load option 
var _load = callbacks[loadCallback].bind(callbacks); 

回答

1

你右邊的新代碼跟蹤。 selectize documentation指出:

加載(fn) - 通過調用提供的函數加載選項。該函數應該接受一個參數(回調),並在結果可用時調用回調。

這裏的重要部分是選擇不關心數據在何處或如何獲得。獲取數據可以同步或異步進行,因爲它所關心的是參數callback()

這一點在你的代碼中有點混亂,但你仍然可以在那裏看到它。你的_load()函數完成它通過回調參數應該做的事情。但是,自定義函數直接返回其值。雖然這不是錯誤的,但它會讓你以錯誤的方式思考。

// Get custom load function from select element data attribute 
var loadCallbackSync = $(this).attr('data-load-callback'); 

// we have this wrapper function that calls our custom load function 
var _load = function(query, callback) { 
    var result = window[loadCallbackSync](query); 
    // -> returns our result 

    callback(result); 
}; 

// if we take the same approach with async loading... 
var loadCallbackAsync = $(this).attr('data-load-callback'); 

var _load = function(query, callback) { 
    var result = window[loadCallbackAsync](query); 
    // -> oh noes! 

    callback(result); 
}; 

儘管同步功能return使用callback()小號荷蘭國際集團的數據和異步功能的常見模式,我們真正需要做的是將數據導入selectize的回調函數。事實證明,你根本不需要_load()。您可以簡單地編寫自定義函數,以便通過選擇直接使用它們。

(我沒能找到selectize到接受query參數一個load()功能的任何引用。然而,包括它或刪除是微不足道的。)

var callbacks = { 
    loadStatesSync: function (query, selectizeCallback) { 
     var states = [ 
      // ... 
     ]; 
     var result = doSomethingWithQuery(states, query); 

     selectizeCallback(result); 
    }, 
    loadStatesAsync: function (query, selectizeCallback) { 
     $.ajax({ 
      // do something with query..., 
      success: function (result) { 
       selectizeCallback(result); 
      } 
     }); 
    } 
} 

var fnName = $(this).data('load-callback'); 
var _load = callbacks[fnName]; 

$(this).selectize({load: _load}); 

很容易得到混爲一談異步概念與使用回調,但我希望這有助於澄清這一點!

+0

謝謝您的詳細解釋。我遇到的一個問題是我的代碼在這裏過於簡單化了,可能在事後並不聰明。在我的實際代碼中,我還使用了兩個可選參數,這些參數允許用戶在返回的數據中指定一個「密鑰」,並限制要返回的記錄數。例如: 回調(窗口[loadCallback](查詢)[loadKey] .slice(0,loadLimit)); 因爲我現在有一個匿名函數聲明,與返回的數據相關,所以這種切片數據的方法將不起作用。有什麼辦法可以獲取這些參數嗎? –

+0

沒有看到代碼,我無法提供很多幫助,但有很多方法可以實現。不過,在最基本的層面上,你只需要確保你所擁有的任何影響最終結果的變量都在你的各種加載函數的範圍內。然後你可以在你的加載函數中訪問這些變量來修改你的狀態數據。你可以在'var result = doSomethingWithQuery(states,query);'這一行上得到這種感覺。如果'query'作爲閉包的一部分,而不是被傳入該函數,那麼您可以使用它來更改加載到selectize中的內容。 – thewildpendulum

+0

我更新了我原來的問題,並決定現在如何解決問題。 –