Почему filterJSON не работает с более сложной иерархией JSON? - PullRequest
0 голосов
/ 30 января 2010

Я хотел бы использовать jQuery filterJSON с flickr, и я обнаружил, что он отображает удаленные файлы JSON, а не только локальные, как показано на демонстрационной странице автора. При замене пути по умолчанию к локальному файлу JSON на удаленный файл Twitter JSON он отображается нормально. НО при использовании других JSON-каналов, таких как flickr JSON в приведенном ниже коде, возвращает неопределенную переменную и ничего не рендерится, почему это так? Я многократно просматривал код плагина построчно и до сих пор не могу понять, почему это только делает твиттер JSON.

Я должен что-то упускать из виду и был бы признателен за вашу помощь. Большое спасибо!

Это работает:

$('body').filterJson({
 data : 'http://twitter.com/status/user_timeline/billgates.json?count=10&callback=?',
 limit : 2,
 anchorWrap : '[p]',
 nextText : 'See More',
 prevText : 'Go Back',
 transition: 'fade',
 delay : 400,

 complete : function(i, r) {
       <code>$('body').append('[p]' + r[i].text + '[/p]')}</code>  // [p] replace [] with brackets as the code tag does not seem to be working for me :(

Это не работает: ... Почему?

$('body').filterJson({
 data : 'http://api.flickr.com/services/feeds/photos_public.gne?tagmode=any&id=7218238@N08&format=json&jsoncallback=?',
 limit : 2,
 anchorWrap : '[p]',
 nextText : 'See More',
 prevText : 'Go Back',
 transition: 'fade',
 delay : 400,

 complete : function(i, r) {
       <code>$('body').append('[img src="'+r[i].items.media.m+'" /]')}</code>  // [img /] replace [] with brackets as the code tag does not seem to be working for me :(

== ДАЖЕ более глубокая иерархия JSON ==

({
    "something1": {
        "someArray": [{
            "1stproperty": {
                "text": "textstring",
            },
            "2ndproperty": "moretext",
            "image": [{
                "t1": "r1"
            },
            "t2": "r2"
            }]
        }] 
    }
})

Ответы [ 3 ]

4 голосов
/ 30 января 2010

filterJSON ожидает массив элементов в результате JSON, тогда как Flickr предоставляет один родительский объект в результате, который содержит массив элементов внутри свойства items этого родительского объекта.

Это внутреннее ограничение в filterJSON, которое нельзя исправить, не изменив сам плагин следующим образом:

24a27
>      itemsLocation: null,
39a43,49
>        if (options.itemsLocation && $.isArray(options.itemsLocation)) {
>          // extract the items from the object hierarchy
>          $.each(options.itemsLocation, function () {
>            r = r[this];
>          });
>        }
>

Затем можно указать массив имен свойств (например, itemsLocation: ['items'] для результата Flickr), чтобы извлечь элементы, с которыми нужно работать filterJSON.

Рабочая демоверсия

http://jsbin.com/enudu3 (редактируется через http://jsbin.com/enudu3)

Полный источник

https://gist.github.com/290420

/*
 * filterJSON v.9.1 - http://www.jeffrey-way.com
 * Last Updated: January 29, 2009

 * When you attach a JSON file, it will parse it with getJSON, and then allow you to filter through and display the items on the page according to 
 * a specified limit, delay, transition, etc. 

 * Developed by Jeffrey Way
 * http://jeffrey-way.com/filterjson-a-jquery-plugin/
 * jeffrey@effrey-way.com
 * Modified by Brian Peiris
 * http://twitter.com/brianpeiris
*/

(function($) {

    $.fn.filterJson = function(options) {

        var defaults = {
            anchorWrap : '<p>',
            complete : null,
            data : null,
            delay : 500,
            limit : 5,
            index : 0,
            transition : 'fade',
            itemsLocation: null,

            nextId : 'next',
            nextText : 'More',

            prevId : 'prev',
            prevText : 'Last'
        },

        options = $.extend(defaults, options);

        this.each(function() {

            var $this = $(this);

            $.getJSON(options.data, function(r) {
                if (options.itemsLocation && $.isArray(options.itemsLocation)) {
                    // extract the items from the object hierarchy
                    $.each(options.itemsLocation, function () {
                        r = r[this];
                    });
                }

                // add the NEXT button
                $this
                   .after(options.anchorWrap)
                   .next()
                   .append('<a></a>')
                   .children()
                   .attr('href', '#')
                   .attr('id', options.nextId)
                   .text(options.nextText);

                // Get first set of items
                options.index = getItems(r);                

                // when the user clicks the NEXT button
                $('a#' + options.nextId).live('click', function() { 

                    // If a previous button doesn't exist, create it!
                    if($('a#' + options.prevId).length == 0) {
                        $this
                           .after(options.anchorWrap)
                           .next().append('<a></a>')
                           .children()
                           .attr('href', '#')
                           .attr('id', options.prevId)
                           .text(options.prevText);                 
                    }

                    // If the user chose the "slide" transition, slideUp...otherwise fadeOut.
                    if(options.transition === 'slide') $this.slideUp(options.delay, emptyAndContinue);
                    else $this.fadeOut(options.delay, emptyAndContinue);        

                    // remove the current items and get the next set, passing in the json file - represented by "r"
                    function emptyAndContinue() {
                        $this.empty();
                        options.index = getItems(r);
                    }                   

                    return false;
                }); // end nextId click     


                // When the previous button is clicked, add the NEXT button if one doesn't exist.
                $('a#' + options.prevId).live('click', function() {
                    if($('a#' + options.nextId).length == 0) {
                        $this
                           .after(options.anchorWrap)
                           .next().append('<a>')
                           .children()
                           .attr('href', '#')
                           .attr('id', options.nextId)
                           .text(options.nextText);
                    }   

                    // If the user chose the "slide" transition, slide up...oitherwise fadeOut
                    if(options.transition === 'slide') $this.slideUp(options.delay, emptyAndContinue);
                    else $this.fadeOut(options.delay, emptyAndContinue);

                    // remove the current items and get the next set, passing in the json file - represented by "r"
                    function emptyAndContinue() {
                        $this.empty();
                        options.index = getPreviousItems(r);                        
                    }                   

                    return false;                   
                }); 

                return this;

            }); // end getJSON

            // Acccepts the parsed JSON file as a parameter "r", and then gets the next set of items. 
            function getItems(r) {  

                var i = options.index, // the current index, or offset. 
                    dataLength = r.length; // total # objects in the JSON file.

                    (function append() {            
                        if(i === dataLength) {$('a#' + options.nextId).remove(); return; } // if the index is equal to total # of items in JSON file, remove the "next" link and exit.
                        if(i >= options.limit + options.index) return; // if index is gte to the current index + the limit, return because reached the max.

                        options.complete(i, r); // call userdefined "complete" function, which appends necessary html to the page.

                        // If the user chose the "slide" transition, slide up...oitherwise fadeOut                      
                        if(options.transition === 'slide') $this.slideDown(options.delay);
                        else $this.fadeIn(options.delay);
                        i++;
                        append(); // Rinse and repeat until i equals the limit          
                    })();   

                // Increase INDEX by current offset to allow for the next grouping.
                return options.index + options.limit;
            } /// end getItems


            // Used when the PREVIOUS BUTTON is clicked. 
            function getPreviousItems(r) {
                // Need to reduce the current options.index back to what it would have been on the previous page. A bit confusing...
                var i = options.index - options.limit * 2;          

                (function append() { // if the user has chosen to delay the appearance of each new image...     
                    if(i === 0) $('a#' + options.prevId).remove(); // If i = 0, we don't need a previous button.        
                    if(i >= options.index - options.limit) return;

                    options.complete(i, r); // call userdefined "complete" function, which appends necessary html to the page.

                    if(options.transition === 'slide') $this.slideDown(options.delay);
                    else $this.fadeIn(options.delay);
                    i++;
                    append(); // Rinse and repeat until i equals the specified options.limit.
                })();       

                // REDUCE index by the limit, because "PREVIOUS BUTTON" was clicked
                return options.index - options.limit;
            } /// end getPreviousItems



        }); // end this.each



    };  // end plugin. Go eat some cake.

})(jQuery);
0 голосов
/ 30 января 2010

Попробуйте это:

complete : function(i, r) {
       $('body').append('[img src="'+r.items[0].media.m+'" /]')} 

Глядя на json, кажется, что первый возвращает массив объектов (r [i]), а второй возвращает только один объект. Одним из полей в этом объекте (items) является массив.

Это должно работать для вас. (Однако я не думаю, что плагин будет работать так, как ожидалось, поскольку он ожидает массив и получает один объект.)

0 голосов
/ 30 января 2010

Поскольку вы получаете доступ к фиду , а не к API с URL-адресом Flickr. Формат канала должен быть либо в формате Atom, либо в формате RSS. Он не вернет вызов JavaScript, а скорее данные в выбранном формате.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...