绑定动态服务器响应(嵌套json) [英] Binding dynamic server response (nested json)

查看:162
本文介绍了绑定动态服务器响应(嵌套json)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个名为的动态数据绑定函数汇编,它需要(2)输入参数:




  • 服务器响应(JSON) - 嵌套json对象

  • 指令集(JSON) - 控制绑定的配置对象。






  • 问题: 该功能目前不会绑定嵌套的json。



    问题: 需要更改哪些使其能够支持所需的输出?






    当前输出:

     < form class =myForm> 
    < div class =myFirstName> john< / div>
    < div class =myLastName> doe< / div>
    < div> john.doe@gmail.com< / div>
    < div>这是静态注入元素< / div>
    < div class =myNestedContainer>
    //这里是我的问题
    // 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>这是静态注入元素< / div>
    < div class =myNestedContainer>
    //这里是我的问题
    // 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> john< / div>
    < div class =myLastName> doe< / div>
    < div> john.doe@gmail.com< / div>
    < div>这是静态注入元素< / 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>这是静态注入元素< / div>
    < div class =myNestedContainer>
    < span class =myUserAge> 25< / span>
    < span class =myUserDob> 1991< / span>
    < span class =myRace> white< / span>
    < / div>
    < / form>






    服务器响应:

      response = [
    {
    first:john
    last:doe,
    email:john.doe@gmail.com,
    个人资料:{
    age:26,
    dob: 1990,
    race:white
    }
    },
    {
    first:jane,
    last:doe,
    电子邮件:jane.doe@gmail.com,
    个人资料:{
    age:25,
    dob:1991,
    race:white
    }
    }
    ]

    指示集:

     指令= {
    标签:form,
    属性:{class:myForm},
    children:{
    first:{
    标签:div,
    属性:{class myFirstName},
    content:null
    },
    la st:{
    标签:div,
    属性:{class:myLastName},
    content:null
    },
    email:{
    标签:div,
    content:null
    },
    myFakeTag:{
    标签:div,
    content:这是一个静态注入元素
    },
    个人资料:{
    标签:div,
    属性:{class:myNestedContainer},
    children:{
    age:{
    tag:span,
    属性:{class:myUserAge},
    content:null
    },
    dob :{
    tag:span,
    属性:{class:myUserDob},
    content:null
    },
    race:{
    标签:span,
    属性:{class:myRace},
    内容:null
    }
    }
    }
    }
    }






    组装功能:

      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){
    casetag:
    var tag = document.createElement(_instr [b]);
    break;
    caseattributes:
    for(a in _instr [b]){
    tag。 setAttribute(a,_instr [b] [a]);
    }
    break;
    caseevents:
    for(a in _instr [b]){
    _instr [b] [a] .forEach((l)=> {
    tag.addEventListener(a,l);
    });
    }
    break;
    casecontent:
    tag.innerHTML =(_instr [b] === null)?o [k]:_instr [b];
    break;
    casech ildren:
    for(var _i in _instr [b]){
    _(_ instr.children [_i],_ i,tag);
    }
    break;
    }
    !! _ n&&& !!标签&& _n.appendChild(tag);
    }
    返回标签;
    })(instr,null);
    };
    (()=> {
    for(i in data){
    var test = gen(data [i]);
    n.appendChild(test);
    }
    })();
    return n;
    }


    解决方案

    这些更改是您希望如何使用和扩展说明。这些与以前有些不同,但重要的一点是, 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;
        })();
    }
    

    这篇关于绑定动态服务器响应(嵌套json)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆