我有以下代码设置,使用jQuery和MagicSuggest初始化单个字段的自动建议功能。这是相对简单的。我已经模块化了一些,因为我打算使用它来初始化其他字段以及MagicSuggest。一个无关的部分是规范名称转换,但这是我正在使用的特定数据集的必要功能。 (我遇到的麻烦问题解释如下...)我如何概括这套Javascript方法,包括promise?
/**
* 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')
});
});
}
必须有它推广的一种方式,但我是新的承诺和$.Deferred
所以我一直在打的理解墙。
我将使用MagicSuggest实例化的其他字段将使用$.getJSON()
方法的不同URL(可能全部使用ID)(用于查找用户以前选择的内容,从而预先填充字段的内容),并且对于这些调用显然会有不同的JSON响应。所以,对我来说,麻烦点是如何让这一切合作,仍然干。
当我开始分崩离析addDefaults()
我打的问题,因为ms
在resultPromise.done
不定,所以在他们的ID,和json
结构$.each
命令中的网址。
你会如何重构这个更可重用?关于承诺和延期的意见/解释总是有帮助的。