2016-06-13 9 views
0

I Versuch bin eine dynamische Datenbindungsfunktion assemble genannt zu bauen, die (2) Eingangsparameter erfolgt:Binding dynamische Serverantwort (nested json)

  1. server response (JSON) - nested json Objekt.
  2. instruction set (JSON) - ein Konfigurationsobjekt, das die Bindung steuert.

Das Problem: Die Funktion derzeit nicht verschachtelten json binden.

Die Frage: Was muss ich es in der Lage die gewünschte Ausgabe unterstützen zu machen ändern?


Der Stromausgang:

<form class="myForm"> 
    <div class="myFirstName">john</div> 
    <div class="myLastName">doe</div> 
    <div>[email protected]</div> 
    <div>this is a static inject element</div> 
    <div class="myNestedContainer"> 
     //HERE IS MY PROBLEM 
     //RETURNS undefined 
     <span class="myUserAge">undefined</span> 
     <span class="myUserDob">undefined</span> 
     <span class="myRace">undefined</span> 
    </div> 
</form> 
<form class="myForm"> 
    <div class="myFirstName">jane</div> 
    <div class="myLastName">doe</div> 
    <div>[email protected]</div> 
    <div>this is a static inject element</div> 
    <div class="myNestedContainer"> 
     //HERE IS MY PROBLEM 
     //RETURNS undefined 
     <span class="myUserAge">undefined</span> 
     <span class="myUserDob">undefined</span> 
     <span class="myRace">undefined</span> 
    </div> 
</form> 

Der gewünschte Ausgang:

<form class="myForm"> 
    <div class="myFirstName">john</div> 
    <div class="myLastName">doe</div> 
    <div>[email protected]</div> 
    <div>this is a static inject element</div> 
    <div class="myNestedContainer"> 
     <span class="myUserAge">26</span> 
     <span class="myUserDob">1990</span> 
     <span class="myRace">white</span> 
    </div> 
</form> 
<form class="myForm"> 
    <div class="myFirstName">jane</div> 
    <div class="myLastName">doe</div> 
    <div>[email protected]</div> 
    <div>this is a static inject element</div> 
    <div class="myNestedContainer"> 
     <span class="myUserAge">25</span> 
     <span class="myUserDob">1991</span> 
     <span class="myRace">white</span> 
    </div> 
</form> 

Die Serverantwort:

response=[ 
    { 
     first: "john", 
     last: "doe", 
     email: "[email protected]", 
     profile:{ 
      age: "26", 
      dob: "1990", 
      race: "white" 
     } 
    }, 
    { 
     first: "jane", 
     last: "doe", 
     email: "[email protected]", 
     profile:{ 
      age: "25", 
      dob: "1991", 
      race: "white" 
     } 
    } 
] 

Der Befehlssatz:

instruction={ 
    tag:"form", 
    attributes:{"class":"myForm"}, 
    children:{ 
     first:{ 
      tag:"div", 
      attributes:{"class":"myFirstName"}, 
      content: null 
     }, 
     last:{ 
      tag:"div", 
      attributes:{"class":"myLastName"}, 
      content: null 
     }, 
     email:{ 
      tag:"div", 
      content: null 
     }, 
     myFakeTag:{ 
      tag:"div", 
      content: "this is a static inject element" 
     }, 
     profile:{ 
      tag:"div", 
      attributes:{"class":"myNestedContainer"}, 
      children:{ 
       age:{ 
        tag:"span", 
        attributes:{"class":"myUserAge"}, 
        content: null 
       }, 
       dob:{ 
        tag:"span", 
        attributes:{"class":"myUserDob"}, 
        content: null 
       }, 
       race:{ 
        tag:"span", 
        attributes:{"class":"myRace"}, 
        content: null 
       } 
      } 
     } 
    } 
} 

der Zusammenfügungsfunktion:

assemble=(data,instr)=>{ 
    var instr = (typeof instr !== "string") ? instr : instr.split('.').reduce((o,i)=>o[i], model); 
    var n = new DocumentFragment(); 
    var gen=(d)=>{ 
     var o = d; 
     return(_=(_instr,k,_n)=>{ 
      for(b in _instr){ 
       switch(b){ 
        case "tag": 
         var tag = document.createElement(_instr[b]); 
         break; 
        case "attributes": 
         for(a in _instr[b]){ 
          tag.setAttribute(a,_instr[b][a]); 
         } 
         break; 
        case "events": 
         for(a in _instr[b]){ 
          _instr[b][a].forEach((l)=>{ 
           tag.addEventListener(a,l); 
          }); 
         } 
         break; 
        case "content": 
         tag.innerHTML = (_instr[b]===null) ? o[k] : _instr[b]; 
         break; 
        case "children": 
         for(var _i in _instr[b]){ 
          _(_instr.children[_i],_i,tag); 
         } 
         break; 
       } 
       !!_n && !!tag && _n.appendChild(tag); 
      } 
      return tag; 
     })(instr, null); 
    }; 
    (()=>{ 
     for(i in data){ 
      var test = gen(data[i]); 
      n.appendChild(test); 
     } 
    })(); 
    return n; 
} 

Antwort

1

Am Ende ändert sich nur, wie Sie die Anweisungen verwenden und erweitern möchten. Diese sind ein wenig anders als die vorherigen, aber eine wichtige Sache ist, dass die appendChild sollte nicht innerhalb die Anweisungen Attribute Schleife für den Knoten aber gleich nach draußen sein; einige Aufmerksamkeit muss auch auf einige spezielle Attribute bezahlt werden, vielleicht class ist nicht der einzige, der weiß :) ... versuchen, die innere for block mit folgendem vollständig zu ersetzen:

var tag = null, a; 
if ('tag' in _instr) { 
    tag = document.createElement(_instr.tag); 

    if ('attributes' in _instr) 
     for(a in _instr.attributes) { 
      a.match(/^class$/) && (a = 'className'); 
      tag.setAttribute(a,_instr.attributes[a]); 
     } 

    if ('events' in _instr) 
     for(a in _instr.events) 
      tag.addEventListener(a,_instr.events[a], false); 

    // 
    // if ('content' in _instr && _instr.content!==null) 
    // tag.innerHTML = _instr.content; 
    // 
    // but take care ... what if is a input[text] 

    tag[_instr.tag=='input' ? 'value' : 'innerHTML'] = ('content' in _instr && _instr.content !== null) ? _instr.content : o[k]; 

    if ('children' in _instr) 
     for(a in _instr.children) 
      _(_instr.children[a], a, tag); 

    !!_n && !!tag && _n.appendChild(tag); 
} 

==== ==============

AKTUALISIERT

jetzt nun der Ausgang ist genau derjenige erwartet. Ich habe sogar einen dummen Fehler behoben, der das Attribut class betrifft. Probieren Sie es aus, vielleicht sogar auf anderen Eingaben, ich habe versucht, Text statt Null auf einige Daten zu setzen, und es sieht gut aus. Wir sehen uns!

function assemble (data, instr) { 
    var n = document.createDocumentFragment(), i; 
    function create(d) { 
     return (function _(_instr, _d, _key, _n) { 
      var tag = null, i; 
      if ('tag' in _instr) { 
       tag = document.createElement(_instr.tag); 

       tag.innerHTML = 'content' in _instr && !!_instr.content ? _instr.content : typeof _d == 'string' ? _d : ''; 

       if ('attributes' in _instr) 
        for (i in _instr.attributes) 
         tag.setAttribute(i, _instr.attributes[i]); 

       if ('events' in _instr) 
        for(i in _instr.events) 
         tag.addEventListener(i,_instr.events[i], false); 

       //recur finally 
       if ('children' in _instr) { 
        for (i in _instr.children){ 
         _(_instr.children[i], _d[i], i, tag); 
        } 
       } 
       !!_n && _n.appendChild(tag); 
      } 
      return tag; 
     })(instr, d, null); 

    } 
    return (function(){ 
     for (i in data) { 
      n.appendChild(create(data[i])); 
     } 
     return n; 
    })(); 
} 
+0

Ok Ich habe das einfach kopiert und es wird kein "innerHTML" in irgendwas davon gesetzt. Die Art und Weise, wie ich es ursprünglich hatte, war "Inhalt: null" und sollte den "Wert" wie im aktuellen "prop: value" verwenden. Ich könnte auch, wenn ich einen String wie diesen Inhalt statisch hinzufügen wollte: 'my string'', und dann, wenn ich nichts wollte, würde ich die' content'-Requisite überhaupt nicht hinzufügen. –

+0

Was willst du als html ?? Der Schlüssel ?? ... nur || k in der Zuweisung – fedeghe

+0

Ja der aktuelle 'key: value'. Wenn ich console.log 'o [k]' gebe, gibt es genau das, was ich will, aber wenn sein Nest (Sub-Level) wie "Alter, Dob, Rasse" ist dann gibt es mir nur das Objekt. –