【问题标题】:How do I generalize this set of Javascript methods, including promises?如何概括这组 Javascript 方法,包括 Promise?
【发布时间】: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


    【解决方案1】:

    经过几天的休息后,头脑清醒了,加上this post 的洞察力,我意识到我不需要为了添加默认值而做这一切。值得庆幸的是,只需将以下内容添加到 init 即可完美运行:value: msField.attr('data-default').split(','),(我正在通过 PHP 将值添加到 HTML 中的 data-default 属性下。

    代码:已删除。

    问题:已解决。

    【讨论】:

      猜你喜欢
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 2015-01-13
      • 2019-03-03
      • 2015-03-09
      相关资源
      最近更新 更多