Tabulator从4.9升级至5.3报错:表格未初始化——调用value函数
解决Tabulator 5.3版本"Table Not Initialized"错误
问题概述
将MediaWiki中的Tabulator组件从4.9升级到5.3后,控制台抛出如下错误:
Table Not Initialized - Calling the value function before the table is initialized may result in inconsistent behavior, Please wait for the
tableBuiltevent before calling this function.
问题根源是Tabulator 5.x改用异步初始化流程,原有列格式化器中直接调用cell.getValue()的逻辑,会在表格未完成初始化时执行,触发错误。同时表格创建逻辑嵌套在fetch请求中,但该请求是获取多语言数据的必要步骤。
修复方案
核心修改是避免在格式化器中直接调用cell.getValue(),转而通过行数据对象获取所需值,同时摒弃对Tabulator内部私有属性的直接访问,改用官方公开API。
修改后的完整代码
document.addEventListener("DOMContentLoaded", function(){ const multiStringFilter = function customHeaderFilter(headerValue, rowValue, rowData, filterParams) { let passed = true; headerValue.toLowerCase().split(" ").forEach(function(filterWord) { let value = rowData[filterParams.column]; if (value === null) value = ''; if (value.toString().toLowerCase().indexOf(filterWord) < 0) { passed = false; } }); return passed; } // 修改catName格式化器:从行数据直接取值,替代getValue() const catName = function categoryName(cell, formatterParams, onRendered) { const value = cell.getData()[cell.getField()]; return categories[value]; } // 修改linkify格式化器:用公开API获取行数据,摒弃内部私有属性访问 const linkify = function functionLinks(cell, formatterParams, onRendered) { const rowData = cell.getData(); const value = rowData[cell.getField()]; const href = rowData.href; return `<a href="${href}">${value}</a>`; } let categories = []; let functions = []; const functionContainers = Array.from(document.getElementsByClassName("calc_functions")); functionContainers.forEach(function(item, index) {categories.push(item.previousElementSibling.querySelector(".mw-headline").innerText)}); functionContainers.forEach( function(cat, index) { Array.from(cat.getElementsByTagName("a")).forEach( function(link) { functions.push( {"catID":index,"function":link.innerText,"href":link.getAttribute("href")} ) }, index) } ); const columns = [ {title:"Link", field:"href", visible:false}, {title:"Function", field:"function", headerFilter:"input", headerFilterFunc: multiStringFilter, headerFilterFuncParams: {column: 'function'}, formatter:linkify, width:200}, {title:"Category", field:"catID", headerFilter:"autocomplete", headerFilterParams:{ values: true, listItemFormatter:function(value, title){ return categories[value]; }, showListOnEmpty: true, allowEmpty: true, freetext: true, }, formatter:catName, width:300}, ]; let paginationElement = document.getElementById("calc_functions_tableNav").querySelector("span"); const langsRequest = new Request("/index.php?title=Documentation/Calc_Functions/Tabulator_langs"); fetch(langsRequest).then((response) => { if (!response.ok) { throw new Error(`HTTP error! Status: ${ response.status }`); } return response.text(); }).then(function(html) { let parser = new DOMParser(); let doc = parser.parseFromString(html, "text/html"); let locale = mw.config.get("wgPageContentLanguage"); let langs = JSON.parse(doc.getElementById("calc_function_langs").textContent); let table = new Tabulator("#calc_functions_table", { data:functions, columns:columns, locale:locale, langs:langs, layout:"fitDataTable", pagination:"local", paginationElement:paginationElement, paginationSize:10, paginationSizeSelector:[10, 25, 50, 100, true], }); }).catch(function(err) { console.warn("Something went wrong.", err); }); });
关键修改点
catName格式化器:- 替换
cellComp.getValue()为cell.getData()[cell.getField()],直接从行数据对象中提取当前列的字段值,避免触发初始化前的getValue()调用。
- 替换
linkify格式化器:- 用
cell.getData()获取完整行数据,替代cellComp.getRow()._row.data(内部私有属性,易引发兼容性问题)。 - 从行数据中直接读取
href和当前列值,避免依赖未初始化的表格方法。
- 用
额外说明
如果后续还有其他依赖表格初始化的操作,可以监听Tabulator的tableBuilt事件,确保在表格完全构建完成后执行:
table.on("tableBuilt", function(){ // 这里执行需要表格初始化完成的操作 });
内容的提问来源于stack exchange,提问作者buovjaga
相关产品推荐
相关产品推荐

