更新时间:2023-01-17 08:04:00
这些更改是您希望如何使用和扩展说明。这些与以前有些不同,但重要的一点是, appendChild
不应该内的节点的指令属性循环,而是在之后在外面必须注意一些特殊的属性,也许 class
不是唯一的一个,谁知道:) ...
尝试完全取代内部块
包含以下内容:
var tag = null,a;
if('tag'in _instr){
tag = document.createElement(_instr.tag);
if('attribute'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 in _instr.events)
tag.addEventListener(a,_instr.events [a]假);
//
// if('content'in _instr& _instr.content!== null)
// tag.innerHTML = _instr.content;
//
//但要小心...如果是输入[text]
标签[_instr.tag =='input'? 'value':'innerHTML'] =('content'in _instr& _instr.content!== null)? _instr.content:o [k];
if('children'in _instr)
(在_instr.children中)
_(_ instr.children [a],a,标签);
!! _ n&&& !!标签&& _n.appendChild(tag);
}
============== ==
更新
现在输出正是预期的输出。我甚至修复了处理类
属性的愚蠢错误。尝试一下,甚至可能在其他输入,我试图把文本而不是一些数据为空,它看起来不错。看到你!
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 = _instr&&&_ _ _ _ _ __内容的内容_instr.content:typeof _d =='string'?_d:'';
if('attribute'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);
}
返回标签;
})(instr,d,null);
}
return(function(){
for(i in data){
n.appendChild(create(data [i]));
)
return n;
})();
}
I'm attempting to build a dynamic data-binding function called assemble
which takes (2) input parameters:
server response (JSON)
- nested json object.instruction set (JSON)
- a configuration object which controls the binding.
The Problem: The function currently doesn't bind nested json.
The Question: What do I need to change to make it able to support the desired output?
The current output:
<form class="myForm">
<div class="myFirstName">john</div>
<div class="myLastName">doe</div>
<div>john.doe@gmail.com</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>jane.doe@gmail.com</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>
The desired output:
<form class="myForm">
<div class="myFirstName">john</div>
<div class="myLastName">doe</div>
<div>john.doe@gmail.com</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>jane.doe@gmail.com</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>
The server response:
response=[
{
first: "john",
last: "doe",
email: "john.doe@gmail.com",
profile:{
age: "26",
dob: "1990",
race: "white"
}
},
{
first: "jane",
last: "doe",
email: "jane.doe@gmail.com",
profile:{
age: "25",
dob: "1991",
race: "white"
}
}
]
The instruction set:
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
}
}
}
}
}
The assemble function:
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;
}
In the end the only thing that changes is how you want the instructions to be used and extended. These are a bit different from the previous but one important thing is that the appendChild
should not be inside the instructions attributes loop for the node but right after outside it; some attention must be payed to some special attributes as well, maybe class
is not the only one, who knows :) ...
try to completely replace the inner for block
with the following :
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);
}
==================
UPDATED
Now the output now is exactly the one expected. I even fixed a stupid bug handling the class
attribute. Try it out, maybe even on other inputs, I tried to put text instead of null on some data and it looks fine. See You!
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;
})();
}