我在写信息管理系统的前端页面,决定使用 jquery 来实现前后端分离,具体的方法是在前端 script 里面使用 ajax 来异步带着数据访问后端,然后根据后端返回的 json 来渲染前端的页面,至于我为什么会遇到闭包这个东西呢?听我慢慢道来 ...
当时写的代码是传给后端 token,然后后端根据 token 对应的用户的权限返回要加载的选项卡,后端功能很好实现,直接这么写就行了
token, isOk := c.GetPostForm("token")
if !isOk {
c.JSON(200, map[string]interface{}{
"msg": "fail",
})
return
}
if !service.CheckToken(&token) {
c.JSON(200, map[string]interface{}{
"msg": "fail",
})
return
}
if service.CheckRoot(&token) {
c.JSON(200, map[string]interface{}{
"msg": "ok",
// TODO
})
return
}
infoBacks := []pojo.InfoBack{{
ButtonId: "info",
ObjUrl: "/info",
ButtonName: "个人信息",
}, {
ButtonId: "room",
ObjUrl: "/room",
ButtonName: "寝室",
}, {
ButtonId: "clean",
ObjUrl: "/clean",
ButtonName: "卫生检查",
}, {
ButtonId: "break",
ObjUrl: "/break",
ButtonName: "报修",
}, {
ButtonId: "lost",
ObjUrl: "/lost",
ButtonName: "失物招领",
},
}
c.JSON(200, map[string]interface{}{
"msg": "ok",
"infos": infoBacks,
})
实现接口之后我就把视线转到前端了,先 F12 里的 console 里测试了下,可以接收到 json 数据,然后就开始写 js 了,大致思路的根据传回的数据,遍历所有元素然后创建 li 标签加按钮,最后把创建出来的按钮绑定上 click 事件的函数
初版代码是这样的
<script charset="utf-8">
$(function() {
$("#quit").click(function() {
var token = localStorage.getItem("token");
localStorage.removeItem("token");
var tks={"token":token}
$.post(
"/quit",
tks,
function() {
location.assign("/login");
}
);
});
var token = localStorage.getItem("token");
$.post(
"/index",
{"token": token},
function(data) {
var indexs = data
for(var i = 0; i < data.infos.length; i++) {
$("#menu").append("<li class=\"nav-item\"><button class=\"my-2 btn btn-secondary btn-block w-100\" type=\"button\" id=\"" + data.infos[i].button_id + "\">" + data.infos[i].button_name + "</button></li>");
$("#" + data.infos[i].button_id).click(function() {
$.get(
indexs.infos[i].obj_url,
function() {
console.log("6")
}
)
});
}
// TODO
}
);
});
</script>
既然是初版代码,那必然是有问题的,运行结果是标签渲染出来了,但是按钮按下去无事发生,console 里没显示 6,后端的日志也没有显示 404 的 get 请求(那些端口我都没写好
可喜可贺的是我在 console 里仔细看了下发现了在按下按钮之后他报错了,说indexs.infos[i] is undefined
,然后我大概知道了是怎么一回事,绑定函数的过程不包括执行,所以再次运行的时候它是独立出来运行的,这时候 i 就不见了,所以就报错了
那么怎么解决这个问题呢?凭我的经验肯定不能解决这种问题,借助了强大的搜索引擎,我找到了和我遇到类似问题的人 🔗
下面是能够 work 的代码
<script>
function(data) {
var indexs = data;
for(var i = 0; i < data.infos.length; i++) {
$("#menu").append("<li class=\"nav-item\"><button class=\"my-2 btn btn-secondary btn-block w-100\" type=\"button\" id=\"" + data.infos[i].button_id + "\">" + data.infos[i].button_name + "</button></li>");
(function(i) {
$("#" + data.infos[i].button_id).click(function() {
$.get(
indexs.infos[i].obj_url,
function() {
console.log("6")
}
)
});})(i)
}
}
</script>
一个人同时写前后端真的挺累的,不过成就感倒是有的,web 也就这回事