我有以下代碼設置,使用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
命令中的網址。
你會如何重構這個更可重用?關於承諾和延期的意見/解釋總是有幫助的。