我正在编写一个jQuery插件,它接收一个 json 文件数组,然后我需要编译成一个大数组。
到目前为止,代码的不同部分都有自己的工作,但是一旦我把它放在一起,我就无法返回新的数组。
我假设要么我不理解如何从嵌套循环中返回值,要么$ .get()是 Asynchronous 并且$ .each()循环是同步。或者两者兼而有之。
我尝试过使用jQuery $ .Deferred但没有运气。关于如何解决这个问题的任何指示都非常欢迎。
这是截至目前的插件代码。我已经对代码进行了评论,因此我应该很容易看到我想要做的事情:
(function ( $ ) {
$.fn.presspull = function( options ) {
// This is the defaults settings which can be changed via the plugin call.
var settings = $.extend({
// These are the defaults.
template : Handlebars.compile( $('#pressTemplate').html() ),
placeHolder : $("#press-grid"),
addMoreBtn : $("a#press-show-more"),
segment : 4,
dataSource : []
}, options ); // end settings
// non mutable elements which can not be changed from the plugin call.
var cache = {
pressArray : new Array(),
compileCount: 0,
segmentItt : 0
}; // end cache
/*============================================================================
– Compile Source: function to build and sort the combined press.
==============================================================================*/
function compileSource() {
// check if the data source contains anything.
if ( settings.dataSource.length > 0 ) {
// for each json file in the data source do...
$.each( settings.dataSource , function( k, v ) {
// get the data
$.get( v, function( data, status, xhr ){
// next loop through the output
$.each( data, function( i, e ){
// add each entry to the pressArray
cache.pressArray.push( e );
}); // end each
// once done do..
}).done( function() {
// compile count increments for every data source
cache.compileCount ++;
if ( cache.compileCount == settings.dataSource.length ) {
cache.pressArray.sort( function( a, b ) {
var c = new Date(a.date),
d = new Date(b.date);
return c>d ? -1 : c<d ? 1 : 0;
}); // end sort
// after compiling and sorting the new list we return it.
}; // end if
// if there is a failure in getting the data it's logged as following
}).fail( function() {
console.log("Failed to get data from: " + v );
}); // end get.done
}); // end each
} else {
console.log("Source files not found!");
};
return console.log( cache.pressArray);
}; // end compileSource
}; // end $.fn.presspull
}( jQuery ));
json文件如下所示:
[
{
"publication": "Dazed & Confused",
"date": "2013-05-01",
"region": "UK",
"cover": "{{ 'img-press-cover-dazed-2013.png' | asset_url }}",
"pressmedia": [
{
"name":"soma",
"image": "Document Name 1 - General",
"description": "description for image 1",
"keyproduct": "link to the key product on the image"
},
{
"name":"soma2222",
"image": "Document Name 2 - General",
"description": "description for image 1",
"keyproduct": "link to the key product on the image"
}
]
]
插件调用如下:
$().presspull({
dataSource : [
"http://link/to/external/json/file/01",
"http://link/to/external/json/file/02",
"http://link/to/external/json/file/03"
]
});
答案 0 :(得分:1)
这里的问题是你的方法compileSource
是异步的,这意味着当你尝试从方法中返回数组时,你的ajax内容将不会完成,所以你将获得一个空数组。
解决方案是使用回调
function compileSource(callback) {
// check if the data source contains anything.
if ( settings.dataSource.length > 0 ) {
// for each json file in the data source do...
$.each( settings.dataSource , function( k, v ) {
// get the data
$.get( v, function( data, status, xhr ){
// next loop through the output
$.each( data, function( i, e ){
// add each entry to the pressArray
cache.pressArray.push( e );
}); // end each
// once done do..
}).done( function() {
// compile count increments for every data source
cache.compileCount ++;
if ( cache.compileCount == settings.dataSource.length ) {
cache.pressArray.sort( function( a, b ) {
var c = new Date(a.date),
d = new Date(b.date);
return c>d ? -1 : c<d ? 1 : 0;
}); // end sort
callback(cache.pressArray)
// after compiling and sorting the new list we return it.
}; // end if
// if there is a failure in getting the data it's logged as following
}).fail( function() {
console.log("Failed to get data from: " + v );
}); // end get.done
}); // end each
} else {
console.log("Source files not found!");
};
}; // end compileSource
//call the compile method
compileSource(function(array){
//this function will be called once all the data is received and sorted, the sorted array will be passed as an argument
})