layer Iframe 传值设计模式(在下献丑了)

分享 未结 8 652
Hide
Hide 2019-8-14
悬赏:20飞吻
----------------------------上次更新(2019-8-16)---------------------------------------------------
1.新增/修改layer.js=》close方法 2处代码,如下图所示


2.申明1个全局变量,每个页面都调用这个js(global.js)


3.组件化封装,openDialog(打开iframe)的函数




4.父传子,以及子接收数据




5.子传父,以及父接收


回帖
  • sadkilo
    2019-8-18
    其实iframe的传值很早就有比较好的解决方案,只需要1个简单工具函数的函数即可完美解决
    原理:
    不管是父页面,还是子页面,还是孙页面, 都有一个顶级的top, (父页面的top即为自己)
    因此我们可以将top 看作云, 各个页面间的传值都先经过云

    /**iframe的传值函数**/
    function iframeData(attr,val){
    var top = window.top;
    var cache=top['_CACHE'] || {};
    top['_CACHE'] =cache;
    return (arguments.length===1) ? cache[attr] : cache[attr] = val;
    };

    例子 父传给子
    父页面传递值 iframeData("parentname","来自父页面的你");
    子页面获取值 iframeData("parentname");

    例子 子传给父
    子页面传递值 iframeData("childname","来自子页面的你");
    父页面获取值 iframeData("childname");

    0 回复
  • Hide
    2019-8-18
    @sadkilo
    (之前2019-8-16优化版忘记更新,现在上述已经更新)

    不得不说你提供的确实是一种方法,之前私聊贤心,他的回答也正是你这种设计模式,但是我之所以没有采取这样的设计是因为以下原因,请看以下分析:

    1.每个页面交互,你都将数据缓存在顶级窗口的全局变量 ['_CACHE']中 ,虽然说是数据集中管理,但是每次交互导致顶级窗口数据越来越大,消耗的内存越来越多,且不会被自动回收,性能会降低

    2.你在实现的时候,为了避免获取数据紊乱,从而提高代码的复杂性如(刻意避免被重复,设计的时候就考虑了要 以后传值 页面编号,方法编号)
    iframeData("page001-methed1",data)
    iframeData("page001-methed2",data)
    iframeData("page002-methed1",data)
    iframeData("page002-methed2",data)

    3.设计理念可能有点跟我的需求有点不符,b与c交互,数据从却要从a拿


    4.对比我的设计模式,优缺点分析(你提供的设计模式以下我简称方案A,我的设计模式以下我简称方案B):
    ⑴. 侵入性对比:方案A获胜
    方案A(未修改源码),方案B(修改了2处layer.js的源代码,提高layui升级风险性)
    ⑵.其他需配置复杂性:方案A微胜
    方案A(定义了一个全局函数 iframeData)
    方案B(定义了一个全局变量postInData,封装openDialog函数仅为降低原生layer的配置复杂性,即使不封装此函数也可以使用,毫无影响)

    ⑶.性能对比:方案B微胜
    方案A(每传值回调都将持续增大内存消耗,所有页面的交互信息都存储在顶级窗口cache中)
    方案B (仅单次会话传值回调,结束后内存会被释放)

    ⑷.规范性、方便性、数据可靠性:方案B获胜
    方案A(通过iframeData函数传值,页面交互都要从顶级窗口再次拿值)
    =》数据可靠性:
    如通过b页面打开c页面,选择了一个数据 并通过iframeData函数取得回调值进行回调操作,但是又打开了一次c页面,然后直接点击右上方的x关闭了窗口取消了本次操作,这样可能导致iframeData函数取值还是原先的数据,又执行了一次操作,而实际第二次并未选择任何数据,这样导致获取到的数据不可靠,可能为缓存数据(当然了,也可以通过额外判断来分辨,但是 b和c交互却要通过a来拿数据可靠性肯定不如 b与c直接交互数据可靠)

    =》规范性:一般(传参需编号页面、方法,否则可能覆盖顶级窗口数据)
    =》方便性:取值、传值 一般


    方案B(配置化传值、回调)
    =》规范性:规范(通过配置化传参、回调)
    =》方便性:data 传参、回调函数 end 获取backData
    =》数据可靠性:data 传参、回调函数 end 获取backData,页面直接交互,没有中间商赚差价



    综上所述:在某些场景下方案A更适用,在规范性、安全可靠性 方案B更通用
    0 回复
  • sadkilo
    2019-8-18
    1.首先,存值用的是{}, 所以同一个业务的传值次数, 不会使内存增加;
    除非业务种类实在很多, 或者传值是一个很大体积的数据, 否则不用考虑 内存溢出.
    如果你是有代码洁癖, 那么新增一个数据清除的函数就好了, 每次数据使用后清除
    function iframeDelData(attr){
    var top = window.top;
    var cache=top['_CACHE'];
    if(cache && attr){
    delete cache[attr];
    }
    };

    第二, 引用你最后一句
    综上所述:在某些场景下方案A更适用,在规范性、安全可靠性 方案B更通用
    你怕是转牛角尖了[黑线]
    ①技术上的通用性
    首先, iframeData不局限于 layer, 只要用到iframe且不出现跨域的情况, 都适用
    而你的方案, 必须要用layer
    ②业务上的通用性
    举例有一个业务场景
    A-->B-->C(A打开B,B又可以打开C)
    如果业务上需要, A传值给B, 而A 又需要传值给C;
    这时候, 你的方案, 使用上就很不便, 由于你的是点对点的传值, 所以 iframe的层级不同, 用户就要额外针对情况编写代码
    而iframeData, 由于用了top作为中间层, 所以业务上,是全场景通用的
    总结, 在通用性上, iframeData完胜

    结论, 你的方案, 如果项目组选定了layer , 其实也可以用, 但是偏偏需要修改源码; 如果后续我要更新layui或layer怎么办?每次都要记得修改layer的代码? 如果项目组换人了, 以后谁还记得?
    所以...你的方案,基本可以淘汰
    最后 提醒一句, 代码入侵,,不到最后不要考虑.......
    0 回复
  • Hide
    2019-8-18
    ①技术上的通用性
    首先, iframeData不局限于 layer, 只要用到iframe且不出现跨域的情况, 都适用
    而你的方案, 必须要用layer
    ②业务上的通用性
    举例有一个业务场景
    A-->B-->C(A打开B,B又可以打开C)
    如果业务上需要, A传值给B, 而A 又需要传值给C;
    这时候, 你的方案, 使用上就很不便, 由于你的是点对点的传值, 所以 iframe的层级不同, 用户就要额外针对情况编写代码
    而iframeData, 由于用了top作为中间层, 所以业务上,是全场景通用的
    总结, 在通用性上, iframeData完胜
    我觉得你说的太绝对,太片面了
    ①技术上的通用性
    首先, iframeData不局限于 layer, 只要用到iframe且不出现跨域的情况 这半句我认同
    但是我的方案, 必须要用layer,这句恐怕你的描述存在偏差,首先既然我用了layui为前端框架,那么我窗口操作用的layer组件肯定是没问题的,但是如果你说就是不想用layer,当然没问题,你看我核心封装代码,似乎跟layer没关系吧,childframe.postInData=postData,这样的写法都是通用的,原生的写法。父传子,完全没问题吧。子传父,那么关闭窗口函数回调 backData传值,也没任何问题,换了任何一个框架都适用,我之前的框架没使用任何layui框架以及组件,就是这套传值模式,没任何问题,也出现弹窗组件混用的情况也没出现问题

    ②业务上的通用性
    我这边的系统 A->B->C、D->D、E、F->E、F,再多的窗口也没问题,首先是通过2个页面直接交互,传值安全性保障,而且没有任何不便




    相反的,你的设计模式,A打开了B,B打开了C,操作完了C(C窗口已经关闭),这个时候点击B右上角的X,相当于取消了本次所有操作,但是你A缓存着C操作后的记录,这样就是一个非常严重的bug,性能姑且不提。

    第二, 你说的如果后续我要更新layui或layer怎么办?
    好,这个完全可以给你一个完美的解释:我是这么做仅仅提高了风险,不代表你的0风险,凡是layer有方法,传参方式、名称等发生了改变,意味着着原先用到layer的页面都会报错。
    使用旧版和我修改版的,升级后都有巨大的风险,比如旧版升级风险80%,我修改后的旧版风险率85%,结果都是死路一条。

    谈论学术的问题建议不要夹杂个人感情,分享自己的设计本来就是让别人来指出自己的不足以便改进的,不仅是提高自己,还让其他使用者看到新的设计思路。但是你这个iframeData完胜,我的方案基本可以淘汰的话倒是真的看不出来完胜在哪个地方,不过可能在你业务场景比较适用我倒是可以理解。所谓仁者见仁智者见智吗,其他layui使用者这看到2套方案对比,自然会有自己心目中的选择。

    0 回复
  • sadkilo
    2019-8-18
    你自己玩, 我懒得费口水了[哈欠]
    0 回复
  • Hide
    2019-8-18
    @sadkilo 慢走不送
    0 回复
  • Hide
    2019-8-18
    talk is cheap,show me the code。用代码说话,好的代码设计大家自然接受,光打嘴炮,理论又空洞,没有实质性的东西的别来。
    0 回复
  • FreakElync
    2019-9-23
    大佬你好,我现在引用的是layui,版本为2.4.5。该帖子对应文件都是加密过后的,请问大佬,怎么才能做如帖子所述的修改
    0 回复