【发布时间】:2014-12-20 06:42:49
【问题描述】:
我有以下代码设置来使用 jQuery 和 MagicSuggest 初始化单个字段的自动建议功能。这是相对简单的。我已经对它进行了一些模块化,因为我打算使用它来初始化其他字段以及 MagicSuggest。一个无关的部分是规范名称转换,但它是我正在使用的这个特定数据集的必要功能。 (问题我在下面解释时遇到了麻烦......)
/**
* Initialize Flights From autosuggest feature
* @return {void}
*/
function initFlightsFromAutosuggest() {
// Flights From Typeahead *************************************
var msField = $('#magicsuggest.direct_flights_from');
var ms = msField.magicSuggest({
id : 'direct_flights_from',
name : 'direct_flights_from',
minChars : 1,
highlight : false,
valueField : 'id',
displayField : 'name',
placeholder : getMSPlaceholder(msField, 'City'),
resultAsString: true,
useTabKey : true,
useCommaKey : true,
useZebraStyle : true,
hideTrigger : true,
sortOrder : 'canonical_name',
maxDropHeight : 500,
data : '/api/v1/cities',
defaultValues : msField.attr('data-default').split(','),
renderer : function(data) { return convertCanonical(data.canonical_name) }
});
// Once loaded, add pre-selected values if there are any
$(ms).on('load', addDefaults(ms, msField));
}
/**
* Gets placeholder value for MagicSuggest instances
* @param {element} el DOM element
* @param {string} defaultString Default string to use
* @return {string}
*/
function getMSPlaceholder(el, defaultString) {
if (el.attr('data-default').length > 0) {
return '';
}
return defaultString;
}
/**
* Converts canonical name into city, state string (dropping country, fixing spacing)
* @param {string} canonical_name Full canonical name
* @return {string} Short name, without country
*/
function convertCanonical(canonical_name) {
if (typeof canonical_name !== 'undefined') {
canonical_name = canonical_name.replace(',United States', '');
canonical_name = canonical_name.replace(',', ', ');
return canonical_name;
}
// Not sure what to do if it's undefined
return;
}
说了这么多,下面是我必须做的,用之前提交的数据预先填充这个字段。
/**
* Adds pre-selected values (ids) loaded into the 'data-default' attribute into the input field
* @param {object} ms MagicSuggest instantiation
* @param {element} msField DOM element used by MagicSuggest
*/
function addDefaults(ms, msField) {
// Get the default attribute value as an array
var defaultIds = msField.attr('data-default').split(',');
// Setup array of requests
var requests = [];
// Push all the requests into an array
$.each(defaultIds, function(index, id) {
requests.push($.getJSON('/api/v1/cities/' + id));
});
// Create a promise, and when all the requests are done (promises fulfilled)
// Send the args (json) to the .done callback
var promise = $.when.apply($, requests).then(function () {
var args = Array.prototype.slice.call(arguments);
return args.map(function(arg) { return arg[0] });
});
// Setup the callback function for 'done'
promise.done(function(json) {
// Setup results array
var results = [];
// Got an auth error from the API, so return early. No results.
if (typeof(json[0].auth) === 'object') {
return false;
}
// For each item, add the proper structure to the results array
$.each(json, function (index, id) {
results.push({
value: json[index][0]['city']['id'],
name: json[index][0]['city']['name']
});
});
var resultPromise = $.when.apply($, results).then(function () {
var args = Array.prototype.slice.call(arguments);
return args.map(function(arg) { return arg });
});
resultPromise.done(function(results) {
ms.setValue(results);
ms.setDataUrlParams({});
$('.input')
});
});
}
必须有一种方法来概括这一点,但我是 Promise 和 $.Deferred 的新手,所以我一直在理解。
我将使用 MagicSuggest 实例化的其他字段将为 $.getJSON() 方法使用不同的 URL(尽管可能都使用 ID)(用于查找用户之前选择的内容,从而预填充字段的内容with),并且显然会对这些调用有不同的 JSON 响应。所以,对我来说,问题在于如何让这一切一起工作并且仍然干燥。
当我开始拆分addDefaults() 时,我遇到了问题,因为ms 在resultPromise.done、带有ID 的URL 以及$.each 命令中的json 结构中未定义。
您将如何重构它以使其更可重用?对 promises 和 deferred 的评论/解释总是很有帮助的。
【问题讨论】:
标签: javascript jquery magicsuggest