Scope for getJSON in jQuery

2019-06-09 08:43发布

I'm having a bit of trouble trying to manage scope when using getJSON.
So on a HTML page I have an unordered list to be filled with list items from a JSON file. The list is markup for a carousel.

HTML:
<ul class="carousel"></ul>

JS:

grabJSON : function() {
    $.getJSON('file.json', function(data) {
        var items = [];
        $.each(data.foo, function(k, v) {
            items.push('<li>' + v.bar + '</li>');
        }
        $('ul.carousel').append(items.join(''));
        // carousel action here
        $('ul.carousel').carouselFunction({
            // carousel options here
        });
    });
}

Currently, I have to place the carousel function within the getJSON function. If I make another function for setting up the carousel, I lose the scope within getJSON.

What is a preferred method of breaking this out so I can have a setupCarousel : function() that is called from getJSON? Normally if I want to call a function from another function in an object I can just go this.setupCarousel(), however with nested scope I'm not sure how to handle this.

Also, outside of the getJSON function I do not have access to any of the elements that were appended. So I can access ul, but not any of the list items created while adding them from getJSON.

2条回答
萌系小妹纸
2楼-- · 2019-06-09 09:20

The $.getJSON call is asynchronous. So, if you do this:

thing.grabJSON();
do_some_other_stuff();

The do_some_other_stuff will be executed before the $.getJSON call finishes. You have to put everything inside the $.getJSON callback because that piece of code will be executed at some time in the future; the callback is free to pass any data it receives to other functions (as in Kishnore's answer) but code that is executed after $.getJSON (where after means after in the source code) can't depend on the $.getJSON call doing anything.

You could do something like this:

function buildCarousel(items) {
    $('ul.carousel').append(items.join(''));
    $('ul.carousel').carouselFunction({
        // carousel options here
    });
}

// ...

grabJSON : function(cb) {
    $.getJSON('file.json', function(data) {
        var items = [];
        $.each(data.foo, function(k, v) {
            items.push('<li>' + v.bar + '</li>');
        }
        cb(items);
    });
}

//...

thing.grabJSON(buildCarousel);

if you wanted to separate the $.getJSON from what needs to be done with that JSON. In this particular case, breaking it apart like the above is more busy work than real work but that sort of pattern (callbacks within callbacks, callbacks all the way down) is pretty common when dealing with AJAX.

查看更多
可以哭但决不认输i
3楼-- · 2019-06-09 09:42

Did you Try something like this?

grabJSON : function() {
    $.getJSON('file.json', function(data) {
        var items = [];
        $.each(data.foo, function(k, v) {
            items.push('<li>' + v.bar + '</li>');
        }
        makeCarousel(items);
    });
}
//pass items to make carosuel function and use it this should solve your problem.
makeCarosuel: function(items) {
$('ul.carousel').append(items.join(''));
        // carousel action here
        $('ul.carousel').carouselFunction({
            // carousel options here
        });
}
查看更多
登录 后发表回答