2009-05-01 8 views
2

Jeder weiß eine gute Möglichkeit, ein JSON-Objekt in verschachtelte Formularfelder zu konvertieren.Konvertieren eines JSON-Objekts in verschachtelte Formularfelder?

Zum Beispiel: Betrachten Sie ein JSON-Objekt:

{'a':{'b':{'c':'1200'}}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}} 

Ich sollte erhalten:

{'a[b][c]':'1200', 'z':'foo', 'bar[baz]':'1', 'bar[id]':2}; 

Irgendwelche Ideen?

Ich benutze derzeit jQuery und es fühlt sich an, als ob so etwas schon existiert, wenn nicht, kann ich einfach meinen eigenen mit einem verrückten Algorithmus rollen, aber ich würde lieber etwas mit einer nachgewiesenen Erfolgsbilanz verwenden.

+1

Was ist ein verschachteltes Formularfeld? Sind diese Feldset-Elemente? Ich verstehe nicht ganz, welchen Algorithmus man eigentlich vom ersten Objekt auf das zweite Objekt übertragen möchte. – Anonymous

+0

Ähm, was genau ist das Chaos? Vielleicht müssen Sie etwas Klärung geben, weil dies ohne mehr Kontext keinen Sinn ergibt. –

+0

Wäre die Tatsache, dass Sie bereits auf Elemente verweisen können als obj ['a'] ['b' ['c' ] Ändern Sie Ihren Formularfeld-Traversierungsalgorithmus etwas besser? – Thevs

Antwort

3

Also, ich habe keine Ahnung, warum Sie tun wollen, was Sie sagen, dass Sie tun wollen, und ich hoffe, Sie werden uns alle füllen, aber dieser Code sollte nahe genug sein, dass Sie in der Lage sind, es zu optimieren basierend auf some code of mine that I use to find differences in JavaScript object graphs) ist:

function doStrangeThing(obj) { 
    var propertyChanges = []; 
    var objectGraphPath = []; 
    (function(obj, refObj) { 
     if (obj.constructor == Object || (obj.constructor != Number && 
      obj.constructor != String && obj.constructor != Date && obj.constructor != Boolean && 
      obj.constructor != RegExp && obj.constructor != Function)) { 
      for (var property in obj) { 
       objectGraphPath.push((objectGraphPath.length > 0) ? "[" + property + "]" : property); 
       if (obj[property].constructor != Function) { 
        if (!refObj[property]) refObj[property] = {}; 
        arguments.callee(obj[property], refObj[property]); 
       } 
       objectGraphPath.pop(); 
      } 
     } else if (obj.constructor != Function) { 
      if (obj != refObj) { 
       propertyChanges.push("\"" + objectGraphPath.join("") + "\":\"" + obj.toString() + "\""); 
      } 
     } 
    })(obj, {}); 
    return "{" + propertyChanges.join(",") + "}"; 
} 

Hier ist, was ich tat, um es zu testen:

doStrangeThing({'a':{'b':{'c':'1200'}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}}); 

die in diesem Wert ergibt:

{"a[b][c]":"1200","z":"foo","bar[baz]":"1","bar[id]":"2"} 

Hoffnung, die Sie in irgendeiner Weise ...

+0

Sobald dies die Serverseite erreicht, wird es in PHP zu einer verschachtelten Hash-Map. – user86847

+0

Nun, wenn es für Sie funktioniert, markieren Sie es bitte als Antwort - ich weiß nichts über PHP oder die Notwendigkeit dafür, aber offensichtlich haben Sie Ihre Gründe.:) Nochmals, es könnte wahrscheinlich ein wenig Optimieren verwenden, um es GENAU so zu machen, wie du es gerne hättest, aber das war relativ schnell für mich zum Testen und Spielen, da ich diesen Code schon vor einiger Zeit geschrieben hatte ... –

+0

Wenn ich "Tweak" sage, meine ich übrigens, dass die Wertetypen korrekt funktionieren - ich sehe, dass Sie den Wert von "bar [id]" als Literalzahl 2 und nicht als String ("2") verwenden möchten.) - Sie können den Code optimieren, um zu testen, ob etwas eine Zahl ist, und wenn nicht, verwenden Sie keine Zitate; etc. –

1
obj = {'a':{'b':{'c':'1200'}}}, 'z':'foo', 'bar':{'baz':'1', 'id':2}} 

ist intern entspricht

{['a']['b']['c']:'1200', ['z']:'foo', ['bar']['baz']:'1', ['bar']['id']:2} 

Bitte beachten Sie, dass dies nicht JSON-Objekt nicht mehr sinnvoll ist.

Sie können bereits erste Objekteigenschaften auf diese Weise beziehen:

var z = obj['a']['b']['c'] // 1200 

Ist es genug für Ihre Bedürfnisse? Möchten Sie Eigenschaftsnamen wirklich in Variablen umwandeln?

+0

Ich musste lachen, als ich diese Antwort las, weil ich denke, ich fühle das gleiche Gefühl, das ich hatte, als ich die Frage las - also WTF ist dieser Typ, der mit diesem Durcheinander macht ?! Es war trotzdem eine interessante Übung, aber ich weiß nicht, was "unknown" mit diesen Sachen in PHP macht. Komisches Zeug. –

+0

Eigentlich bekam ich, was er wollte. Ziemlich komisch, aber es hat etwas Sinn. Es gibt jedoch viele einfachere algorithmische Wege, um das gleiche Ziel zu erreichen ... Und es würde ein großes Durcheinander mit Variablennamen und Namensräumen geben, wenn es für den allgemeinen Gebrauch hätte implementiert werden sollen. – Thevs

0

Ich würde eigentlich eine Funktion empfehlen, die ein verschachteltes JSON-Objekt nimmt und es in eine HTTP-POST-Zeichenfolge verwandelt. jQuery akzeptiert das für all seine Argumente, die HTTP-Parameter benötigen.

Ich habe die Funktion unten in mehreren Produktions apps (Benutzung auf eigene Gefahr) geschrieben und verwendet:

$.httpSerialize = function(items, parentName) { 
    var serializedItems = [], serialize = arguments.callee, encodeItem =  function(key, value) { 
     if (value === null || typeof value == 'undefined') return value; 
     if (value.constructor == Array) {return serialize(value, key);} 
     return (value.constructor == Object) 
      ? serialize(value, key) 
      : (value === true || value === false) 
       ? key+"="+new Number(value) 
       : key+"="+encodeURIComponent(value); 
    }; 

    if (items.constructor == Array) { 
     parentName = parentName || 'item'; 
     for (var i = 0; i < items.length; i++) { 
      var key = parentName+'['+i+']', value = items[i]; 
      serializedItems.push(encodeItem(key, value)); 
     } 
    } else { 
     parentName = parentName || ''; 
     for (var key in items) { 
      var value = items[key]; 
      if (parentName) { 
       serializedItems.push(encodeItem(parentName+'['+encodeURIComponent(key)+']', value)); 
      } else { 
       serializedItems.push(encodeItem(encodeURIComponent(key), value)); 
      } 
     } 
    } 
    return serializedItems.join("&"); 
};