layui ajax回调了两次怎么解决,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】

【JavaScript】

form.render(null, 'test1'); //更新 lay-filter="test1" 所在容器内的全部表单状态

form.render('select', 'test2'); //更新 lay-filter="test2" 所在容器内的全部 select 状态

//……

解决方法

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

form.render('select');

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

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

那里有最完整的代码。

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

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

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

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 = '县';

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');

});

}

);

总结:

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

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

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

友情提示:

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