javascript的webstorage数据存储问题,不能直接存undefined

这篇文章分享一下自己使用sessionStorage遇到的一个小问题,以后遇到要避坑。

需求是easyui表格的单元格编辑,点击保存的时候会结束当前行的编辑,然后修改editingId(当前编辑行记录的ID)。

目录

一、待解决问题

二、完整的页面代码

三、具体业务逻辑

添加数据

保存数据

编辑数据

四、问题分析

五、问题解决


一、待解决问题

如图,点击修改按钮时无响应,也没有报错。

二、完整的页面代码

menu_list.html

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><link rel="stylesheet" href="/css/themes/icon.css"/><link rel="stylesheet" href="/css/themes/default/easyui.css" /><title>系统管理>>菜单列表</title><script src="/js/public/jquery.min.js"></script><script src="/js/easyui/jquery.easyui.min.js"></script><script src="/js/easyui/easyui-lang-zh_CN.js"></script><script src="/js/public/util.js"></script><script src="/js/public/public.js"></script><script src="/js/public/sessionStorage.js"></script><script src="/js/menu_list.js"></script></head><body><div><a href="javascript:" class="easyui-linkbutton" onclick="insert()">添加</a><a href="javascript:" class="easyui-linkbutton" onclick="edit()">修改</a><a href="javascript:" class="easyui-linkbutton" onclick="save()">保存</a><a href="javascript:" class="easyui-linkbutton" onclick="cancel()">取消</a><a href="javascript:" class="easyui-linkbutton" onclick="expandAll()">展开全部</a><a href="javascript:" class="easyui-linkbutton" onclick="collapseAll()">折叠全部</a></div><div id="mm" class="easyui-menu" style="width:120px;"><div onclick="append()" data-options="iconCls:'icon-add'">添加</div><div onclick="removeIt()" data-options="iconCls:'icon-remove'">删除</div><div class="menu-sep"></div><div onclick="collapse()">折叠</div><div onclick="expand()">展开</div></div><table id="menu_treegrid"></table></body>
</html>

menu_list.js

let parentId;
let data = {id: "",name: "xxx",url: "",icon: "icon-xxx"
};/*** 添加*/
function insert() {let menuId = new Date().getTime();let treegrid = $("#menu_treegrid");treegrid.treegrid("append",{data: [{id: menuId,name: "xxx",url: "/html/xxx",icon: "icon-xxx"}]});// 保存editingId到sessionStoragestorage("editingId", menuId);// 开启行编辑treegrid.treegrid("beginEdit", menuId);
}/*** 修改*/
function edit() {let editingId = getStorage("editingId");console.log(editingId);if (editingId) {$("#menu_treegrid").treegrid("select", editingId);} else {let row = $("#menu_treegrid").treegrid("getSelected");console.log("开始编辑行:");console.log(row);if (row) {storage("editingId", row.id);$("#menu_treegrid").treegrid("beginEdit", row.id);}}
}/*** 保存*/
function save() {let editingId = getStorage("editingId");if (editingId) {let treegrid = $("#menu_treegrid");if (editingId) {// 只有结束编辑才能获取到最新的值treegrid.treegrid("endEdit", editingId);let postData = {id: editingId,name: data.name,url: data.url,icon: data.icon,parentId: parentId};console.log(postData);storage("editingId", undefined);// post("/menu/updateById", postData, function () {// 	storage("editingId", undefined);// }, error);}}
}/*** 取消*/
function cancel() {let editingId = getStorage("editingId");if (editingId) {$("#menu_treegrid").treegrid("cancelEdit", editingId);storage("editingId", undefined);}
}/*** 折叠全部*/
function collapseAll() {$("#menu_treegrid").treegrid("collapseAll");
}/*** 展开全部*/
function expandAll() {$("#menu_treegrid").treegrid("expandAll");
}/*** 添加*/
function append() {let menuId = new Date().getTime();let treegrid = $("#menu_treegrid");let node = treegrid.treegrid("getSelected");parentId = node.id;storage("editingId", menuId);treegrid.treegrid("append",{parent: node.id,data: [{id: menuId,name: "xxx",url: "",icon: "icon-xxx"}]});let editingId = getStorage("editingId");treegrid.treegrid("beginEdit", editingId);
}/*** 删除*/
function removeIt() {let node = $("#menu_treegrid").treegrid("getSelected");if (node) {$("#menu_treegrid").treegrid("remove", node.id);}
}/*** 折叠*/
function collapse() {let node = $("#menu_treegrid").treegrid("getSelected");if (node) {$("#menu_treegrid").treegrid("collapse", node.id);}
}/*** 展开*/
function expand() {let node = $("#menu_treegrid").treegrid("getSelected");if (node) {$("#menu_treegrid").treegrid("expand", node.id);}
}$(document).ready(function() {$("#menu_treegrid").treegrid({url: "/menu/listTreeGrid",method: "get",idField: "id",treeField: "name",fitColumns: true,pagination: true,pageSize: 10,pageList: [10, 20, 50, 100],columns:[[{title: "菜单编号", field: "id", hidden: true},{title: "菜单名称", field: "name", align: "left", editor: "textbox", width: 100},{title: "图标样式", field: "icon", align: "left", editor: "textbox", width: 100},{title: "页面地址", field: "url", align: "left", editor: "textbox", width: 200,formatter: function(value) {if (value) {return "<a href='" + value + "'>" + value + "</a>";} else {return "<div>/</div>";}}}]],onAfterEdit: function (row, changes) {console.log(changes);data = {id: row.id,name: row.name ? row.name : changes.name,url: row.url ? row.url : changes.url,icon: row.icon ? row.icon : changes.icon};;},onContextMenu: function (e, row) {e.preventDefault();$(this).treegrid("select", row.id);$("#mm").menu("show",{left: e.pageX,top: e.pageY});}}).treegrid("clientPaging");});(function($) {function pagerFilter(data) {if ($.isArray(data)) {    // is arraydata = {total: data.length,rows: data}}let dg = $(this);let state = dg.data("treegrid");let opts = dg.treegrid("options");let pager = dg.treegrid("getPager");pager.pagination({onSelectPage:function(pageNum, pageSize) {opts.pageNumber = pageNum;opts.pageSize = pageSize;pager.pagination("refresh",{pageNumber:pageNum,pageSize:pageSize});dg.treegrid("loadData",state.originalRows);}});if (!state.originalRows){state.originalRows = data.rows;}let topRows = [];let childRows = [];$.map(state.originalRows, function(row){row._parentId ? childRows.push(row) : topRows.push(row);});data.total = topRows.length;let start = (opts.pageNumber-1)*parseInt(opts.pageSize);let end = start + parseInt(opts.pageSize);data.rows = $.extend(true,[],topRows.slice(start, end).concat(childRows));return data;}let appendMethod = $.fn.treegrid.methods.append;let loadDataMethod = $.fn.treegrid.methods.loadData;$.extend($.fn.treegrid.methods, {clientPaging: function(jq) {return jq.each(function() {let state = $(this).data("treegrid");let opts = state.options;opts.loadFilter = pagerFilter;let onBeforeLoad = opts.onBeforeLoad;opts.onBeforeLoad = function(row,param) {state.originalRows = null;onBeforeLoad.call(this, row, param);}$(this).treegrid("loadData", state.data);$(this).treegrid("reload");});},loadData: function(jq, data) {jq.each(function() {$(this).data("treegrid").originalRows = null;});return loadDataMethod.call($.fn.treegrid.methods, jq, data);},append: function(jq, param) {return jq.each(function() {let state = $(this).data("treegrid");if (state.options.loadFilter == pagerFilter){$.map(param.data, function(row) {row._parentId = row._parentId || param.parent;state.originalRows.push(row);});$(this).treegrid("loadData", state.originalRows);} else {appendMethod.call($.fn.treegrid.methods, jq, param);}})}});
})(jQuery);

三、具体业务逻辑

添加数据

当点击添加按钮的时候,会在表格末尾添加一行记录,并开启行编辑,使用了sessionStorage保存正在编辑的行数据的ID。

/*** 添加*/
function insert() {let menuId = new Date().getTime();let treegrid = $("#menu_treegrid");treegrid.treegrid("append",{data: [{id: menuId,name: "xxx",url: "/html/xxx",icon: "icon-xxx"}]});// 保存editingId到sessionStoragestorage("editingId", menuId);// 开启行编辑treegrid.treegrid("beginEdit", menuId);
}

保存数据

点击保存会修改editingId的值为undefined,相当于删除

/*** 保存*/
function save() {let editingId = getStorage("editingId");if (editingId) {let treegrid = $("#menu_treegrid");if (editingId) {// 只有结束编辑才能获取到最新的值treegrid.treegrid("endEdit", editingId);let postData = {id: editingId,name: data.name,url: data.url,icon: data.icon,parentId: parentId};console.log(postData);// 修改editingId的值为undefined,相当于删除storage("editingId", undefined);// post("/menu/updateById", postData, function () {// 	storage("editingId", undefined);// }, error);}}
}

编辑数据

选中表格一行,点击编辑按钮,就会根据editingId的值来判断当前有没有行在编辑,如果有的话,选中当前行,但是不结束正在编辑的行。如果没有在编辑的数据行,则开启当前选中行的编辑。

/*** 修改*/
function edit() {let editingId = getStorage("editingId");console.log(editingId);if (editingId) {$("#menu_treegrid").treegrid("select", editingId);} else {let row = $("#menu_treegrid").treegrid("getSelected");console.log("开始编辑行:");console.log(row);if (row) {storage("editingId", row.id);$("#menu_treegrid").treegrid("beginEdit", row.id);}}
}

四、问题分析

点击修改按钮无反应,但是并没有报错,问题很显然,是一直走的if分支,一直在选中当前行。

所以,问题的关键就在editingId的值,上面通过浏览器打印出来的值为undefined,很显然没有什么问题。

但是,致命的就是这里,这里打印的undefined并不是未定义,而是字符串的"undefined"。

直接打印undefined是灰色的,如图,下面的那个是真的undefined

五、问题解决

既然不能直接存undefined,那么就存一个空字符串进去,问题完美解决~

/*** 保存*/
function save() {let editingId = getStorage("editingId");if (editingId) {let treegrid = $("#menu_treegrid");if (editingId) {// 只有结束编辑才能获取到最新的值treegrid.treegrid("endEdit", editingId);let postData = {id: editingId,name: data.name,url: data.url,icon: data.icon,parentId: parentId};console.log(postData);storage("editingId", "");}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/156464.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「更新」Macos屏幕录像工具:ScreenFlow

mac电脑屏幕截图工具哪个好&#xff1f;ScreenFlow是Mac上的一款优秀的屏幕录像软件&#xff0c;它不仅具有屏幕录制功能&#xff0c;还具有视频编辑功能。以下是对ScreenFlow的一些详细介绍&#xff1a; 首先&#xff0c;ScreenFlow可以捕获摄像机、麦克风和计算机音频&#…

如何用ChatGPT进行“论文翻译+润色”?

2024年申报国自然项目基金撰写及技巧最新基于Citespace、vosviewer、R语言的文献计量学可视化分析技术及全流程文献可视化SCI论文高效写作方法 GPT引领前沿与应用突破之GPT4科研实践技术与AI绘图 不夸张说&#xff0c;只要调教好咒语&#xff0c;就必然会形成一场论文翻译润色…

王道p18 3.对长度为n的顺序表L,编写一个时间复杂度为 O(n)、空间复杂度为 O(1)的算法,该算法删除线性表中所有值为x的数据元素。(c语言代码实现)

视频讲解在这里&#xff08;谢谢各位大佬&#xff09; &#x1f447; p18 第三题数据结构课后算法题_哔哩哔哩_bilibili 本题代码如下 void deletex(struct sqlist* s, int x) {int k 0;int i 0;for (i 0; i < s->length; i){if (s->a[i] ! x)//只要不等于x&…

JMeter断言之JSON断言

JSON断言 若服务器返回的Response Body为JSON格式的数据&#xff0c;使用JSON断言来判断测试结果是较好的选择。 首先需要根据JSON Path从返回的JSON数据中提取需要判断的实际结果&#xff0c;再设置预期结果&#xff0c;两者进行比较得出断言结果。 下面首先介绍JSON与JSON…

使用Ansible中的playbook

目录 1.Playbook的功能 2.YAML 3.YAML列表 4.YAML的字典 5.playbook执行命令 6.playbook的核心组件 7.vim 设定技巧 示例 1.Playbook的功能 playbook 是由一个或多个play组成的列表 Playboot 文件使用YAML来写的 2.YAML #简介# 是一种表达资料序列的格式,类似XML #特…

Instagram 运营技巧,这4个基本设置很重要!

ins这个平台相信很多跨境卖家都不陌生&#xff0c;但想要运营好这个平台却不是那么容易的。想要在ins上获得更多的自然流量&#xff0c;基本设置和功能就要搞懂&#xff0c;今天就给大家分享4个基本的ins设置&#xff0c;以及如何更好地使用 Hashtag&#xff01; Instagram Bio…

Ubuntu Desktop 20.04升级gcc-11

默认自带的gcc是9&#xff0c;需要升级到11 sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install gcc-11 sudo apt install g11 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 50 sudo update-alternatives -…

java--java的参数传递机制

1.java的参数传递机制都是&#xff1a;值传递 ①所谓值传递&#xff1a;值的是在传递实参给方法的形参的时候&#xff0c;传输的是实参变量中存储的值的副本。 ②实参&#xff1a;在方法内部定义的变量。 ③形参&#xff1a;定义方法时"(...)"中所声明的参数。 2.…

数据可视化篇——pyecharts模块

在之前的文章中我们已经介绍过爬虫采集到的数据用途之一就是用作可视化报表&#xff0c;而pyecharts作为Python中可视化工具的一大神器必然就受到广大程序员的喜爱。 一、什么是Echarts&#xff1f; ECharts 官方网站 : https://echarts.apache.org/zh/index.html ECharts 是…

区块链-蚂蚁链(阿里系产品),至信链(腾讯系),长安链(国家队)

目录 区块链-蚂蚁链&#xff08;阿里系产品&#xff09;,至信链&#xff08;腾讯系&#xff09;,长安链&#xff08;国家队&#xff09; ①蚂蚁链&#xff08;阿里系产品&#xff09; ②至信链&#xff08;腾讯系&#xff09; ③长安链&#xff08;国家队&#xff09; Hyp…

Unity内打开网页的两种方式(自带浏览器、内嵌浏览器)

1.自带浏览器 这个比较简单&#xff0c;直接调用unity官方的API即可&#xff0c;会直接使用默认浏览器打开网页&#xff0c;这里就不多做解释了。 代码 public InputField input;private void OpenUrlByUnity(){string inputStr input.text;if (!string.IsNullOrEmpty(input…

SQL server数据库端口访问法

最近数据库连接&#xff0c;也是无意中发现了这个问题&#xff0c;数据库可根据端口来连接 网址:yii666.com< 我用的是sql2014测试的&#xff0c;在安装其他程序是默认安装了sql(sql的tcp/ip端口为xxx)&#xff0c;服务也不相同&#xff0c;但是由于比较不全&#xff0c;我…