• JavaScript巧用对象的引用解决三级联动


           在开发过程中,我们经常会有操作需要进行三级联动操作,比较典型的如:省市区的选择,菜单栏的选择等。当我们遇到这个问题的时候,为了便于开发,我们都是通常使用第三方的插件来实现数据的联动效果。这时候按照联动数据,后端往往会给我们一段数据数据格式如图所示:

            但当数据到了前端以后,为了方便,前端往往又需要将数据再次遍历一遍,以便将参数的属性名,或者添加额外字段,而后台为了生成这么一种数据格式,也是已经经过一次遍历的。

    因此,从方案上来说,最好是一遍解决问题的。而这个遍历由前端完成更为合适一点。

            这时候后端给我们的数据格式是这样的。(另外接口)

            此时我们需要做的就是根据code 拼接成合适的含有父子关系的数组。根据后端定义,code 长度为 3 时,是第一级,为 6 时为第二级,以此类推。001 的子元素为 001001, 001 的兄弟元素为 002。

    遍历的代码比较简单,只是在我没有想到在这个地方,根据 对象变量存储的数据是真实对象所在地址字节时 这个概念来进行遍历的时候。对于如何编写这一函数,我无法进行。

              const arr = [
                {
                  "code": "001"
                },
                {
                  "code": "001001"
                },
                {
                  "code": "002"
                },
                {
                  "code": "002001"
                },
                {
                  "code": "002002"
                },
                {
                  "code": "002003"
                },
                {
                  "code": "002004"
                },
                {
                  "code": "002005"
                }
              ]
    
              //因为是值的引用,所以根据这一存储的原理,每次遍历以后都可以将之前的数据补充完整,所以遍历以便以后,
              
              // obj[001]就是code 为001 且包括其所有子元素的一个对象,
              // obj[001001]就是code 为001001 且包括其所有子元素的一个对象(不包括父元素)
              // 而我们obj[001]也早已经将数据保存到了resultArr中。这时候resultArr就是最终结果。
              // (数组也是存储的每个元素的真实所在位置的地址的一个数组)
              let obj =  new Map()  //以 key :value 的形式,根据code存放每个value
              let resultArr = []
              arr.map((currentValue, index, array) => {
                let code = currentValue.code
                obj[code] = currentValue
                //  当code长度为3时,代表为一级目录
                if (currentValue.code.length === 3) {
                  resultArr.push(obj[code])
                } else {
                  let auth = currentValue.auth
                  let parentid = currentValue.code.substring(0, currentValue.code.length - 3)  // 获取当前currentValue的父元素的pid
                  if (obj[parentid].list) {
                    obj[parentid].list.push(currentValue)
                  }
                  else {
                    obj[parentid].list = []
                    obj[parentid].list.push(currentValue)
                  }
                }
              })
              console.log(resultArr)

            说回原理,代码的原理在于 对于对象类数据,值的存储不是存放在栈中,而是存储在堆中,let obj = {} 实际上obj 的真实信息是这个存在与堆中的,而obj实际存储的是这个对象的地址,而使用obj时我们是根据在obj所获取的地址,找到对应的堆数据进行修改。同样的,在上述代码中,我们虽然没有直接修改 resultArr ,但我们通过修改 obj[code] 的值,对于引用obj[code] 的resultArr而言,其内值已经发生变化。简单代码如下

    let obj1 = {
        name:'张三',
    }
    let obj2 = obj1
    
    obj2.name = '李四'
    console.log(obj1.name)  // 李四

           详细内容可以百度或者谷歌搜索 js对象的赋值的引用

     参考资料:JavaScript高级程序设计 第四章 4.1.2 复制变量值

  • 相关阅读:
    Updatepanel 中使用 Timer 控件 失去焦点问题
    获取周一还是周日作为首日
    存储过程
    ASP.NEt ajax 弹出窗口在页面无法关闭
    Gridview 每秒刷新数据
    SharePoint 2013 set site mailbox
    SharePoint 2010 将带有工作流的模板移动到另一个站点集
    Infoapth 使用拼写 并加载web part 在Infopath的页面上
    ECMA 上传文件到SHarePoint 文档库
    数据库如何高效率处理百万以上的查询
  • 原文地址:https://www.cnblogs.com/h246802/p/8797070.html
Copyright © 2020-2023  润新知