javascript - tutorial - Enlace dinámico de respuesta del servidor(json anidado)
solidity español (1)
Estoy intentando construir una función dinámica de enlace de datos llamada assemble
que toma (2) parámetros de entrada:
-
server response (JSON)
- objeto json anidado. -
instruction set (JSON)
: un objeto de configuración que controla el enlace.
El problema: la función actualmente no enlaza json anidado.
La pregunta: ¿Qué necesito cambiar para que sea capaz de soportar el resultado deseado?
El resultado actual:
<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>
El resultado deseado:
<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>
La respuesta del servidor:
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"
}
}
]
El conjunto de instrucciones:
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
}
}
}
}
}
La función de ensamblaje:
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;
}
Al final, lo único que cambia es cómo quiere que las instrucciones se usen y amplíen. Estos son un poco diferentes de los anteriores, pero una cosa importante es que el appendChild
no debe estar dentro del bucle de atributos de instrucciones para el nodo, sino justo después de fuera; también se debe prestar atención a algunos atributos especiales, tal vez la class
no sea la única, quién sabe :) ... intente reemplazar por completo el for block
interno for block
el siguiente:
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);
}
==================
ACTUALIZADO
Ahora el resultado ahora es exactamente el esperado. Incluso arreglé un error estúpido manejando el atributo de class
. Pruébelo, tal vez incluso en otras entradas, traté de poner texto en lugar de nulo en algunos datos y se ve bien. ¡Nos vemos!
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;
})();
}