且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

绑定动态服务器响应(嵌套json)

更新时间: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:

  1. server response (JSON) - nested json object.
  2. 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;
    })();
}