Tencent / tmagic-editor

Other
4.19k stars 707 forks source link

数据源 处理 报错path_1[1] #608

Open GoToBoy opened 4 months ago

GoToBoy commented 4 months ago

根据源码 查找到数据源定义 要用class extend Base

// datasource.ts
export default class MyDataSource extends HttpDataSource {
    constructor(options: any) {
        super({ schema, ...options });
        this.initData();
    }

    async initData() {
        const data = await this.fetchData();
        this.setData(data);
    }

    async fetchData() {
        try {
            const response = await this.app.request?.({
                url: '/api/my-data',
                method: 'GET',
            });
            return response.data;
        } catch (error) {
            console.error('获取数据失败:', error);
            return null;
        }
    }
}
// tmagic.config.js
export default defineConfig({
    packages: [
        path.join(__dirname, '../ui-react'), // 组件
        path.join(__dirname, './datasources'), // 数据源
    ],
    componentFileAffix: '.tsx',
    dynamicImport: true,
    useTs: true,
    datasoucreSuperClass: ['MyDataSource'],
});

问题1: key不存在执行不下去

// packages\runtime-react\node_modules\@tmagic\cli\lib\utils\resolveAppPackages.js
const setPackages = (packages, app, packagePath, key) => {
// ...
if(!key) return;
//...
}

问题2: 把第1个问题处理完后, 遇到第二个报错点:

const getASTTokenByTraverse = ({ ast, indexPath }) => {
// ...
     visitExportDefaultDeclaration(p) {
            const { node } = p;
            const { declaration } = node;
            component = path_1.default.resolve(path_1.default.dirname(indexPath), importSpecifiersMap[declaration.name]);
            this.traverse(p);
        },
// ...
}
// TypeError [ERR_INVALID_ARG_TYPE]: The "paths[1]" argument must be of type string. Received undefined

原因是 declaration.name 为undefined

// fixed:
component = path_1.default.resolve(path_1.default.dirname(indexPath), importSpecifiersMap[declaration.name||'']);

就可以生成对应的datasource-entry.js 入口文件

是我对初始化数据源的定义设定错了,还是这个源码是不完善的?

jia000 commented 4 months ago

自定义数据源的目录结构要跟组件一样,应该是这样 image

然后还要与ui一样有一个index.js,内容如:

import xx form 'xxxx';

const ds = {
 key: xxxx
}

export default ds
GoToBoy commented 4 months ago

可以给一个数据源的demo吗? formConfig.ts / datasource.ts / initValue.ts

jia000 commented 4 months ago

formConfig/initValue 与组件的是一摸一样的,datasource.ts就是你写的MyDataSource

GoToBoy commented 4 months ago

在playground / page 里面这么用吗? Object.entries(dataSources).forEach(([type, DS]: [string, any]) => { DataSourceManager.register(type, new DS({ app })); });

注册到 DataSourceManager 后, 组件怎么用?

GoToBoy commented 4 months ago

还有个问题 DataSourceManager 是 页面的data管理 还是数据源管理的概念 = =?

jia000 commented 4 months ago

在组件的formConfig中加上type: 'data-source-select' / 'data-source-field-select',或者直接在文本输入宽中输入${数据源id.字段name}。然后再组件中的config中就可以获取到对应的数据源数据。

DataSourceManager 中的data就是所有数据源的数据,会自动赋值到config中

jia000 commented 4 months ago

runtime中会监听数据源变化然后更新dsl https://github.com/Tencent/tmagic-editor/blob/20a540f0fc1db7b9c88c59db2cae3141885d9057/runtime/vue3/page/App.vue#L28

DataSourceManager 中会编译好数据源相关的数据,然后生成新的组件配置,通知runtime更新 https://github.com/Tencent/tmagic-editor/blob/20a540f0fc1db7b9c88c59db2cae3141885d9057/packages/data-source/src/createDataSourceManager.ts#L56 https://github.com/Tencent/tmagic-editor/blob/20a540f0fc1db7b9c88c59db2cae3141885d9057/packages/data-source/src/createDataSourceManager.ts#L62