2014-12-20 85 views
0

我有以下代码设置,使用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()我打的问题,因为msresultPromise.done不定,所以在他们的ID,和json结构$.each命令中的网址。

你会如何重构这个更可重用?关于承诺和延期的意见/解释总是有帮助的。

回答

0

在休息了几天之后,我有了一头清新的头脑,并且凭借this post的洞察力,我意识到我不需要这么做就可以添加默认值。值得庆幸的是,只需添加以下到init完美工作:value: msField.attr('data-default').split(','),(我添加的值到HTML通过PHP的data-default属性下

代码:删除

问题:。解决