遇见的问题
之前一直做游戏后端相关开发,接入Luban也一直很顺利,最近学习Cocos,也想接入Luban,发现总是报"TypeError: json is not iterable",查看报错对应代码如下:
constructor(_json_: any) {
this._dataMap = new Map<number, Item>()
this._dataList = []
console.log("TbItem ==>",_json_);
for(var _json2_ of _json_) {
let _v: Item
_v = new Item(_json2_)
this._dataList.push(_v)
this._dataMap.set(_v.id, _v)
}
}
报错行在for(var json2 of json),这部分报错应该是loader写法有问题
解决的过程
查看当前loader相关代码
this.tables = new Tables((file:string):any=>{
resources.load("/data/"+file,(err:any,res:JsonAsset)=>{
if(err){
console.log("LUBAN读表失败",err);
return;
}
return res.json;
});
});
查看JsonAsset相关代码
/**
* @en Json asset, it will automatically parse the json to a JS object.
* @zh Json 资源。
* Json 资源加载后将直接解析为对象。如果你希望获得 JSON 的原始文本,你需要使用文本资源(使用文件名后缀“.txt”)。
*/
export class JsonAsset extends Asset {
/**
* @en The parsed JS object
* @zh 解析后的对象。
*/
json: Record<string, any> | null;
}
发现自己写的loader返回的是Record<string,any>,而Record<string,any>没有迭代器,所以用for … of 遍历就报错了。为了适配Luban生成的代码,要么给Record实现迭代器,要么修改loader相关代码,给Record实现迭代器很难,但修改loader很简单:
protected onLoad() {
this.on("LuBan",this.onLuban,this);
resources.loadDir("/data",JsonAsset,(err,data)=>{
if(err){
console.log("LUBAN读表失败",err);
return;
}
for(let v of data){
this.data.set(v.name,v);
}
this.emit("LuBan");
});
}
onLuban(){
this.tables = new Tables((file)=>{
let __json__:Array<any> = new Array<any>();
let iter = app.manager.table.data.get(file);
if(iter){
for(let v of iter.json){
__json__.push(v);
}
}
return __json__;
});
}
先在onLoad的时候加载所有的json文件,并注册”LuBan“事件,在加载完成的回调函数里面触发LuBan事件。
完整代码
import { JsonAsset, _decorator } from 'cc';
import BaseManager from '../../../../extensions/app/assets/base/BaseManager';
import { resources } from 'cc';
import { Tables } from '../../../res-native/common/schema';
import { app } from '../../../app/app';
const { ccclass, property } = _decorator;
@ccclass('TableManager')
export class TableManager extends BaseManager {
data:Map<string,any>=new Map<string,any>();
tables:Tables;
// [无序] 加载完成时触发
protected onLoad() {
this.on("LuBan",this.onLuban,this);
resources.loadDir("/data",JsonAsset,(err,data)=>{
if(err){
console.log("LUBAN读表失败",err);
return;
}
for(let v of data){
this.data.set(v.name,v);
}
this.emit("LuBan");
});
}
// [无序] 自身初始化完成, init执行完毕后被调用
protected onInited() { }
// [无序] 所有manager初始化完成
protected onFinished() { }
// [无序] 初始化manager,在初始化完成后,调用finish方法
protected init(finish: Function) {
super.init(finish);
}
onLuban(){
this.tables = new Tables((file)=>{
let __json__:Array<any> = new Array<any>();
let iter = app.manager.table.data.get(file);
if(iter){
for(let v of iter.json){
__json__.push(v);
}
}
return __json__;
});
}
}