Layui表单“动态加载select数据,点击两次才出来”的原因与解决方法

今天在用Layui的时候,由于需要做三级联动菜单,当我用“Ajax实现三级联动下拉菜单省市区(PHP+JavaScript)原生代码”的时候,却发现:

 

用了Layui这种前端框架,Layui表单“动态加载select数据时,会导致点击select没有反应或者点击两次才出现下拉列表“的情况。

 

原因:

我首先是保证我的代码是没有任何错误与BUG的,我已经调试过半天了。

最终才发现我主要的问题还是Layui表单“更新渲染”的问题,是由于逻辑有问题所造成的。

 

我也去看了一下Layui手册,Layui表单“更新渲染”官方手册内容如下:

有些时候,你的有些表单元素可能是动态插入的。这时 form 模块 的自动化渲染是会对其失效的。虽然我们没有双向绑定机制(因为我们叫经典模块化框架,偷笑.gif) 但没有关系,你只需要执行 form.render(type, filter); 方法即可。

 

1、第一个参数:type,为表单的 type 类型,可选。默认对全部类型的表单进行一次更新。可局部刷新的 type 如下表:

参数(type)值 描述
select 刷新select选择框渲染
checkbox 刷新checkbox复选框(含开关)渲染
radio 刷新radio单选框框渲染

 

例如:

form.render(); //更新全部
form.render('select'); //刷新select选择框渲染
//……

 

2、第二个参数:filter,为 class="layui-form" 所在元素的 lay-filter="" 的值。你可以借助该参数,对表单完成局部更新。

 

例如:

【HTML】
<div class="layui-form" lay-filter="test1">
  …
</div>
 
<div class="layui-form" lay-filter="test2">
  …
</div>
      
【JavaScript】
form.render(null, 'test1'); //更新 lay-filter="test1" 所在容器内的全部表单状态
form.render('select', 'test2'); //更新 lay-filter="test2" 所在容器内的全部 select 状态
//……

 

解决方法

知道了原因,也看了手册,解决起来就容易多了,主要的原因就是Layui表单“更新渲染”的问题,以我这里为例子,最最主要的代码就是看:

form.render('select');

 

如果是ajax的话,请求成功后,得到返回的数据,Layui表单就需要“更新渲染”。

当看了我以前写的代码的时候,发现我的代码逻辑的确是有问题的,以前写的代码,具体可以去看:

Layui select onchange事件 正确使用教程

那里有最完整的代码。

 

最终,修改后的代码如下:

由于我用的是原生的JavaScript Ajax代码,我之所以出现:Layui表单“动态加载select数据,点击两次才出来”这个问题,无非就是我把 form.render('select'); 位置放错地方了。

因为我忘记了原生的JavaScript Ajax代码并不是按代码顺序从上到下来执行的,它是先ajax请求,成功后,正常返回了数据,再执行相关的JavaScript document渲染代码。

 <script>
            layui.use(['form', 'layedit', 'laydate'], function(){
                    var form = layui.form;
                    form.on('select(Loadprovince)', function(data){
                        //var val=data.value;
                        //console.info(val);
                        var xhttp = new XMLHttpRequest();
                        xhttp.onreadystatechange = function() {
                            if (this.readyState == 4 && this.status == 200) {
                                if(document.getElementById("city").getAttribute("disabled")){
                                    //console.info(100);
                                    document.getElementById("city").removeAttribute("disabled");
                                }else{
                                    //console.info(200);
                                    //document.getElementById("city").setAttribute("hidden","hidden");
                                    document.getElementById("county").innerHTML = '<option value="county">县</option>';
                                    document.getElementById("county").setAttribute("disabled","disabled");
                                }
                                document.getElementById("city").innerHTML = this.responseText;
                                form.render('select');

                            }
                        };
                        //获取省地区的ID并ajax传送到服务端,例如:四川省id=5
                        var data = "province=" + document.getElementById("province").value + "&type=<?php echo $type;?>";
                        //console.log(data);
                        xhttp.open("POST", "<?php echo $HOMEURL.$ADMIN_ADDRESS;?>?action=unique-ajax", true);
                        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                        xhttp.send(data);
                        //form.render();
                        //以前放的位置 form.render('select');
                    });
                    form.on('select(Loadcity)', function(data){
                        //var val=data.value;
                        //console.info(val);
                        var xhttp = new XMLHttpRequest();
                        xhttp.onreadystatechange = function() {
                            if (this.readyState == 4 && this.status == 200) {
                                if(document.getElementById("county").getAttribute("disabled")){
                                    document.getElementById("county").removeAttribute("disabled");
                                }
                                document.getElementById("county").innerHTML = this.responseText;
                                form.render('select');
                            }
                        };
                        var data = "city=" + document.getElementById("city").value + "&type=<?php echo $type;?>";
                        console.log(data);
                        xhttp.open("POST", "<?php echo $HOMEURL.$ADMIN_ADDRESS;?>?action=unique-ajax", true);
                        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                        xhttp.send(data);
                        //form.render();
                       //以前放的位置 form.render('select');

                    });


                }
            );
        </script>

 

总结:

如果你是其它的框架,估计还是会遇到:表单“动态加载select数据时,会导致点击select没有反应或者点击两次才出现下拉列表“的情况。

 

毕竟每个人用的框架不同,代码编程语言也不同。就拿ajax来说,有框架本身支持的语法,也有jquery ajax语法,还有原生的JavaScript ajax语法。虽然说原理都差不多,但是你想兼容就不容易了。

 

就拿我自己亲身体验来说,我用原生的JavaScript ajax语法还要兼容Layui这种框架,我只能换一种思路去修改。谁知道在Layui框架中,纯原生的JavaScript ajax语法居然没作用!你想不改都不行。

 

友情提示:

经过长期的测试,Layui里也可以直接写原生的JavaScript ajax代码,是我自己代码写的有问题,才会造成了原生JavaScript Ajax代码不生效,因此大家可以放心的在Layui框架里写纯原生的JavaScript代码。

    A+
发布日期:2021年03月17日 12:58:02  所属分类:Layui
最后更新时间:2021-03-26 19:58:20
评分: (1 票;平均数5.00 ;最高评分 5 ;用户总数1;总得分 5;百分比100.00)
付杰
Swoole从入门到精通(第一季)
  • ¥ 199.0元
  • 市场价:199.0元
Python爬虫教程:零基础上手Scrapy分布爬虫
  • ¥ 388.0元
  • 市场价:388.0元
C++基础入门到进阶视频教程
  • ¥ 498.0元
  • 市场价:498.0元
数据科学与人工智能:必备数学基础
  • ¥ 298.0元
  • 市场价:398.0元

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: