我已配置selectize.js以从html数据属性收集配置选项。我的一种配置类型是能够指定一个js函数来调用自定义数据加载(在简单的ajax加载之外)。代码运行良好,直到我运行异步的自定义函数。使用异步方法时,selectize.js加载回调在数据加载之前返回。我一直在努力寻找一种方法将selectize.js load()回调传递给自定义加载函数。
这是一个配置为运行" loadStates()"的选择元素。函数获取此特定选择元素的数据:
<select
id="state"
class="selectize"
data-load-type="callback"
data-load-callback="loadStates"
>
这是&#34; loadStates()&#34;要调用的函数。我对这个例子保持简单,但理想情况下,这可以是任何一种方法,包括异步方法。
<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()回调。
我尝试了什么:
我尝试将load()回调函数发送到自定义函数中,如下所示:
// ...
// Call the custom load function
window[loadCallback](query, callback);
// ...
function loadStates(searchQuery, callback) {
callback(
// ... json data here
);
}
但是,没有返回任何数据。
更新 - 使用@thewildpendulum解决方案:
因此,这个load选项具有selectize,这与load()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));
}
}
}
使用用户回调对象和自定义数据切片构建选择性加载选项的新代码
// 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);
答案 0 :(得分:2)
你走在正确的轨道上。 selectize documentation州:
load(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()
。您可以简单地编写自定义函数,以便通过选择直接使用它们。
(我无法在选择接受load()
参数的query
函数中找到任何引用。但是,包括它或删除是微不足道的。)
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});
使用回调很容易让异步概念混淆,但我希望这有助于清除这一点!