Home > Article > Web Front-end > A way to process layui table data changes
Table data changes generally include several contents: adding, modifying, deleting, and moving. A problem often faced in development is how to synchronize data to the node after the change. My personal suggestion has always been to use table overloading. Whether it is url mode or data mode, it actually needs to be reloaded. URL reloading will naturally re-request the background to get the latest data. Data mode is generally an operation on data. Re-render it with new data.
At the same time, we will consider how to reduce requests as much as possible. Perhaps the most profound thing is the update operation. In order to update this record, we need to reload the entire table. It feels like it is not worthwhile to request the data again, so generally speaking, we can use the table The obj.update method in the tool event is used to update.
However, many shortcomings will be found in specific use. This article mainly deals with these shortcomings and gives a tablePlug.update method, and then derives add, remove and move, and new Added method to update statistical row data.
Test page: Comprehensive test page Stream loading form test page Regular refresh form test page
1. update
As mentioned above, obj.update(data) has many limitations. The advantage is that it can update the data with the minimum modification cost, and it will update. The key data in the data in the parameter will not update the entire row or the entire table node; the flaw is that there is a problem with the underlying implementation logic:
1. By traversing the data, the corresponding data in the cache is updated. The value of the recorded key, and then update the content of td according to the configuration information of cols, but if you want to update the toolbar column, it will not work. Currently, only the template is parsed, so if you want to update the toolbar, you can basically set it to templet, and adding a field to this column is theoretically possible.
2. Even if a field is added to the toolbar column and changed to a templet, it may not be updated because the internal implementation logic is to first determine whether the original data has this key, so if the field name is not in the original data , it cannot be updated later using obj.update. This is a relatively big limitation.
Because taking our project as an example, if the data given to us by the background does not have the value of this key in the original record, it will not give a key: '', then if you want to use the obj.update key later, It becomes impossible unless you use parseData to manually initialize the data provided by the background before rendering and add the corresponding key, but you can imagine how troublesome it is.
3. The data is updated one by one, and then the corresponding td is updated when a value is updated. However, there is another risk, that is, the traversal of the object is unordered, such as update{a: 1 , b:2}, if the cols of field a will use the value of field b for processing and then display it.
Then if the traversal sequence is to update the value of a first, and then start to update the content of td of a, at this time the value of b in the cache is still old and not the 2 you want to update, wait until the b field is updated He can't say that if he detects that other fields are using this field, he will update the other party's content again, which leads to the result of a being still wrong.
4. When a certain value of a statistical column is updated, the corresponding data of the statistical row is not recalculated.
To sum up, the implementation of obj.update is still too ideal and too simple. From a data point of view, there is no problem that each key of a record is independent, but it is not the case when it is displayed on the page. Because the content of the page is not always a simple value display of a single field, some special processing will also be performed.
So a templet is needed for conversion and customization, so it is possible that multiple fields will be used in a TD. This is normal. The buttons on the toolbar will also determine whether some buttons are displayed based on the status of the data, etc. .
So I personally think that updating this data cannot be an independent small unit update, but first update the data of this row and then update this row, instead of traversing the updated keys and updating them one by one, and then proceed If you look at it at a larger scale, the records in this table are actually a whole.
It cannot be said that if you change this record, other records will remain unchanged. It does not rule out that the td of a certain field will be processed based on the same field on the current page, such as statistics rows. So the current idea is to directly update the value into the cache first, and then call the rendering tr td content inside the table.
Approximate code:
In the front, some processing is done on the parameters to make the parameters more flexible. The most important thing is the second half of the cache update part, and the most critical part. The renderData method:
His function is to re-parse and render the data in the cache, and at the same time handle whether it is mobile data and which record is clicked by default. But the core is to render the cache and call renderData inside table.js.
Usage scenarios:
1. To know which record is being modified by the current editor, you can take a look at one of the most commonly used scenarios: click edit to pop up a form and then modify and submit it. After completion, I hope you will try not to Re-request the interface to update the data and page.
Gif is very difficult to record. You can use the edit button in the test example to test the effect.
The form of the updated data called is:
tablePlug.update(表格实例的id, 当前tr的index, newData)
2. If you update a record without knowing the current trIndex, there must be a restriction that it must be a table with a primary key, and the updated data must contain the primary key field, otherwise You don't know which record is updated.
tablePlug.update('demo', {id: 10002, username: '贤心'});
3. When updating multiple records at one time, this parameter trIndex is meaningless, and it is useless to add it. Because multiple records are updated, you can write this test
tablePlug.update('demo', [{id: 10002, username: '贤心'}, {id: 10006, username: '小偷', age: 18, sign: '大叔'}]);
On the page, you can take a look at the two test buttons "Points Cleared" and "Female Points Added 100" in the head toolbar and the event execution methods behind them
4. More willfully, as long as Pass in a tableId, and update will render the data currently in the cache. This is very practical. For example, if you feel that the logic parameters in my update are not satisfied with the logic of the cache modification, you can use it yourself and think it is better. method to handle the cache, and finally execute tablePlug.update('demo'), which provides a higher degree of freedom and the possibility of expansion.
2. addData
The records added by addData are data records that have been returned after requesting the interface. They are essentially different, so Don't get confused.
Specific addData code:
In data mode, some records are actually added to the data and then reloaded.
// 添加单条记录: tablePlug.addData ('demo', {id: newId, username: '甲'}); // 添加多条记录 tablePlug.addData ('demo', [{id: newId1, username: '乙'},{id: newId2, username: '丙'}]);
There is a more comprehensive example about addData. You can see how to use the table's data mode in conjunction with stream loading to create a stream-loaded table.
https:/ /sun_zoro.gitee.io/layuitableplug/testTableFlow
3. del
Add and delete actual personal suggestions or reload comparison It is safe, whether it is URL or data mode, so the corresponding processing method for deletion is similar to the actual addition. The only troublesome thing about deletion is that the data mode needs to delete the specified record in the original record.
And it is possible that if the selected status memory is deleted, it is necessary to adjust its status; or for more convenient use, the parameters are also processed,
1. Delete For the specified subscript data, you can view the monitoring processing of the delete button in the toolbar of the table row. However, note that if the table is in URL mode, the current test page is written in json files, so reload will not have any effect.
So if you want to test, please test in data mode. Don’t worry about this. If the URL is an actual service interface, the data will be returned in the background. Generally, if the deletion is successful, subsequent queries will not come out again unless the background interface has a problem.
2. Delete some specified records. This generally has two forms, but the same requirement is that it must be a table with a primary key.
// id集合 tablePlug.del('demo', [1,2,3,4]); // 对象数组 tablePlug.del('demo', [{id: 1, name: 'name1'}, {id:2}, {id:4}]);
Use it according to which data is more convenient. Which form, you can refer to the batch deletion processing method of the test page
4. move
This processing is basically the same as update , adjust the position of the data in the cache, and then call the renderData method inside the component to let it re-render it
Then for the convenience of use, a method of moving up and moving down is derived
Effect
理论上利用一些拖拽事件或者其他的插件在事件中调用一下tablePlug.move('demo', form, to);就能够实现顺序的任意改变了
限制:注意!这个只是针对数据移动,不会有单条数据记录的变动,如果原始的数据里面有点击了排序,那么移动之后默认是会去掉这个排序的状态了的,因为移动之后很可能就不能满足当前的排序规则了,所以建议在使用移动的时候不要跟sort搭配,如果有sort而且所谓的移动是会发起请求改变数据的,那么这个建议还是使用请求接口得到两个新的数据然后用update去更新他们的位置。
五、renderTotal
在记录更新之后,如果存在统计行有需要统计的列,那么值一般也要跟着变,另外一个更加重要的作用就是可以自定义统计规则,而不是自带的求和,可以自定一定计算的函数,或者可以直接类似templet一样的去自定义返回的内容,包括异步的去读取想要显示的数据。
代码大概如下:
从实现代码可以看出就是给cols的字段配置新增一个totalFormat的设置,可以设置一个规则如果不设置的话就是sum(目前也只是添加了sum,其他的规则后面会加入或者自己加入,比如平均。
最大最小不过个人觉得主要意义是可以自定义方法,这个才是实用常用的),也可以设置一个方法,如果不是异步的可以直接把结果返回,如果是需要异步的那么也可以在得到最终想要的结果的时候执行:
tablePlug.renderTotal(tableId, field, res);
比如下面的:
平时实用的话不是都要自己去调用的,在插件内部已经在renderDone回调里面会去执行他了:
参数也是比较自由,不同的组合会有不同的效果,
// 触发更新某个表格的所有列的统计数据 renderTotal(tableId); // 触发更新某个表格的某个字段的数据 renderTotal(tableId, fieldName); // 更新某个表格的某个字段的统计数据为value renderTotal(tableId, fieldName, totalValue);
六、refresh
之前做过一个智能reload的修改,即在执行table.reload的时候会根据传过去的option来判断只是重新请求数据还是需要重载一下,个人觉得效果可以了。
不过对于有强迫症(有追求)的小伙伴来说,在一些场景下还是不够好,就是那些定时刷新的,表现就是一方面滚动条会回到top:0,left:0,还有其他的比如鼠标在操作分页组件的时候会觉得失去焦点,新增一个tablePlug.refresh来试一试能否满足要求。
先看效果:
事件背后做的事情:
表格config:
背后的实现思路
修改table的Class.prototype.pullData支持refresh模式
renderData的时候根据是否refresh去做一些细节的处理,还有一个限定就是返回的数据中关于总数应该是不变的,如果发生了改变,那么还是会renderData,会重新渲染page组件。
另外一个限制就是这种refresh的表格不建议再加什么按钮呀edit呀,因为它一直会在变,基本主要就是用来做一个单纯用来显示用的表格,比如一些经常变化的数据,访问人次,股票动态之类的。
使用:
// 启动表格demo的自动刷新功能,500毫秒一次 tablePlug.refresh('demo', 500); // 取消表格demo的自动刷新 tablePlug.refresh('demo', false); // 停止所有已开启自动刷新的表格的自动刷新 tablePlug.refresh(false);
更多layui框架知识请关注layui使用教程。
The above is the detailed content of A way to process layui table data changes. For more information, please follow other related articles on the PHP Chinese website!