8
votes

Comment créer récursivement de créer des données UL / LI de JSON - plusieurs couches profondes

J'essaie d'utiliser les données JSON suivantes pour créer la structure similaire suivante dans une fonction intérieure récursive avec pas beaucoup de chance, a vraiment besoin d'aide et donc si quelqu'un peut aider s'il vous plaît faire. Merci d'avance.

$.fn.dropdown = function(settings){

    var that = this;
    var settings = $.extend({}, $.fn.dropdown.defaults, settings);

    var methods = {
        createDropDownCode: function(arr){

            // loop through li's of primary menu
            that.find("li").each(function(idx){

                $(this).append( menusort(arr.menu[idx].sub) );

                function menusort(data){
                    if(data !== null)   
                        var html = "<div><ul>";

                    for(item in data){
                        html += "<li>";
                        if(typeof(data[item].sub) === 'object'){
                            html += "<a href='" + data[item].link + "'>" + data[item].name + "</a>";
                            if($.isArray(data[item].sub))
                                html += menusort(data[item].sub);
                        }
                        html += "</li>"
                    }
                    if(data !== null)
                        html += "</ul></div>";
                    return html;
                }
            })
        },
        init: function(){
            var html = methods.createDropDownCode(settings.jsonData);

        }
    }

    methods.init();

}


1 commentaires

À noter, je sais qu'il y a une méthode Isarray à JQuery.


8 Réponses :


6
votes

faire deux fonctions makul et makeli . Makeul Appels Makeli sur chaque élément et appels appels makul s'il y a sous éléments : xxx

http://jsfiddle.net/bvdw3/

doit être adapté à vos besoins, mais vous avez eu l'idée.


0 commentaires

15
votes

Vous pouvez essayer cette fonction récursive que j'ai simplement codée: xxx

Il renvoie le code HTML pour le menu, alors utilisez-le comme celui-ci: var html = buildlist (JSON. Menu, false);

Je crois que c'est plus rapide car il est en pure JavaScript, et cela ne crée pas de nœuds de texte ni d'éléments DOM pour chaque itération. Il suffit d'appeler .innerhtml ou $ ("... '). HTML () à la fin lorsque vous avez terminé au lieu d'ajouter immédiatement HTML pour chaque menu.

jsfiddled: http://jsfiddle.net/remibreton/csql8/


12 commentaires

La concaténation d'une chaîne est-elle plus rapide que d'utiliser jQuery pour créer les éléments DOM?


Il suffit de vérifier, super - on dirait que je peux l'utiliser pour mes besoins ou au moins la moisir à ce que j'essaie d'accomplir. Merci! BTW, y a-t-il des modèles de récursion que je peux utiliser?


Oui, la concaténation est plus rapide que la création d'éléments DOM. Je suis content que cela aide.


Je ne suis pas sûr de ce que vous entendez par des motifs de récursion?


Je viens d'inspecter le HTML qui sort de cette méthode et cela semble être très buggy - chrome est très indulgent, toutes les pensées? semble être une allocation de tags '' vides.


J'ai fait des altérations FE, j'ai ajouté le code (enveloppé dans un plugin) à ce fil pour les autres (et vous-même) à voir.


Ahh à des motifs Je me demande simplement s'il existe des modèles de programmation particuliers utilisés pour la récursivité et sont conçus pour une telle méthode?


D'accord, oui je viens de le réaliser produire des valeurs «indéfinies». Je suis jsfiddling le si vous voulez: jsfiddle.net/reemibreton/csql8


Je ne peux pas voir Jsfiddle, veuillez mettre à jour, vraiment besoin de ce @ Rémibreton


Merci @ Rémibreton. Votre réponse est très utile pour mon travail. Merci beaucoup!


Ce code que vous avez posté m'a aidé à faire la fonction récursive que j'essayais de construire. Merci!


Ouais, en utilisant la fonction récursive!



2
votes

Cette solution utilise une seule fonction récursive. J'ai simplifié la logique en utilisant tableau code> 'S mappe () code> Prototype code> Fonction.

p>

$(function () {
    $("body").html(makeUnorderedList(getData().menu, function(item, index, parent) {
      // `item` and `this` are the same.
      return $('<a>', {
            text : (item.id || item.link),
            href : '#' + (item.id || item.link),
            name : item.name,
            'data-index' : index
        });
    }, 'sub'));
});

function makeUnorderedList(data, mapFunc, childProp, li, parent) {
    return $('<ul>').append(data.map(function (el, index) {
        var li = li || $('<li>');
        li.append(mapFunc.call(el, el, index, parent));
        if (el[childProp]) {
            li.append(makeUnorderedList(el[childProp], mapFunc, childProp, li, data));
        }
        return li;
    }));
}


1 commentaires

Merci, c'était très utile! Apprécié



1
votes

Fiddle

code:

js xxx

html xxx

CSS xxx


0 commentaires

0
votes

Je cherchais une fonction générale d'élément d'enfant parent et j'ai vu ces réponses, Et j'ai pris des morceaux de code d'ici et là et j'ai fait cette fonction. J'ai décidé de partager mon code comme une réponse, Au cas où quelqu'un comme moi trouvera ce post lorsqu'il recherchera une fonction générale de tirage de l'élément HTML HTML HTML: xxx

https://jsfiddle.net/kxn442z5/1/


0 commentaires

1
votes

Ceci est comme une solution complète pour générer une UL / LI récursivement à partir de JSON config, qui contient des classes personnalisables pour chaque nœud et son support d'événements étendus et d'effondrement pour chaque nœud. Ceci fournit juste un modèle de travail de base, à partir duquel vous serez capable de développer et de personnaliser à vos besoins.

J'ai trouvé cette réponse de https://techmeals.com/fe/questions/javascript/ 6 / How-CAN-I-Create-a-dynamic-arbores-de-ul-and-li-from-json-config p>

Exemple de fichier de configuration JSON: P> xxx pré>

code HTML: p> xxx pré>

arbores.js p> xxx pré>

arborescent. /p>

// the variable "config" is nothing but the config JSON defined initially. 
treeNode = new tree($('.treeContainer .tree'), config); 
treeNodeObj = treeNode.getTree();


0 commentaires

3
votes

Pure ES6

   var bar = [
  {
    name: 'Home'
  }, {
    name: 'About'
  }, {
    name: 'Portfolio'
  }, {
    name: 'Blog'
  }, {
    name: 'Contacts'
  }, {
    name: 'Features',
    sub: [
      {
        name: 'Multipage'
      }, {
        name: 'Options',
        sub: [
          {
            name: 'General'
          }, {
            name: 'Sidebars'
          }, {
            name: 'Fonts'
          }, {
            name: 'Socials'
          }
        ]
      }, {
        name: 'Page'
      }, {
        name: 'FAQ'
      }
    ]
  }
]
var result=foo(bar)


0 commentaires

0
votes

Une modification à une ancienne réponse a apporté cette question, et je pense que dans le JS moderne, cela devient plus facile que de nombreuses réponses ci-dessus.

Voici une solution, à l'aide de chaînes de modèle et de la destruction des paramètres: P>

p>

const buildMenu = (nodes) =>
  '<ul>' + nodes.map (
    (node) => node.sub
      ? '<li>' + (node.name ? '<a href="' + node.link + '">' + node.name + '</a>' : node.id) + '<div>' + buildMenu(node.sub) + '</div></li>'
      : '<li>' + (node.id || '<a href="' + node.link + '">' + node.name + '</a>') + '</li>'
  ) .join ('') + '</ul>'


1 commentaires

Oh, attendez, cette dernière version n'est pas ES5, car elle a toujours des fonctions de flèche. Je vais laisser les supprimer comme un exercice pour le lecteur. :RÉ