Dataview 挂了函数到 global 上非常卡(已换用 React Components 插件)

遇到的问题

今天刚刚安装的 Obsidian, 尝试用 dataview 建立跑团人物卡完成自动计算, 用的是 js 查询. 现在这个卡才写了不到一半, 打开不过几分钟就会把整个软件卡死.

页面简述

为了方便, 我挂了些函数到 globalThis 上, 主要复杂的逻辑就只有一张自动表. 页面头部的位置有很多查询.

  • 头部的查询:
- **`$= TRPGHelper.getMetaWithTagVal("职业")`
- **年龄:** `$= TRPGHelper.getMetaVal("年龄")`岁, **体重:** `$= TRPGHelper.getMetaVal("体重")`磅, **身高:** `$= TRPGHelper.getMetaVal("身高")`cm
- **速度:** `$= TRPGHelper.getMetaValWithFix("速度")`尺, **体型:** `$= TRPGHelper.getMetaVal("体型")`, **阵营:** `$= TRPGHelper.getMetaVal("阵营")`
- **种族:** `$= TRPGHelper.getMetaVal("种族")`, **语言:** `$= TRPGHelper.getMetaVal("语言")`
- **HP:** `$= TRPGHelper.getMetaValWithFix("HP")`, **抗性:** `$= TRPGHelper.getMetaVal("抗性") ?? "无"`
  • 页面最开始我用来挂工具函数的代码块:
(() => {
    if (!globalThis?.TRPGHelper) globalThis.TRPGHelper = {};

    globalThis.TRPGHelper.getMetaVal = (key, plus) => {
        const from = dv.current()?.[key];

        let numRes = from?.reduce?.(
            (pre, cur) => pre + Number.parseInt(cur ?? 0),
            0
        );

        if (Number.isNaN(numRes)) return from;

        if (plus && numRes !== null && numRes > 0) numRes = "+" + numRes;

        return numRes ?? from ?? null;
    };

    globalThis.TRPGHelper.getMetaValWithFix = (key, plus) => {
        const fix = Number.parseInt(dv.current()?.[`${key}修正`] ?? 0);

        const fixNotNan = Number.isNaN(fix) ? 0 : fix;

        const unfixed = TRPGHelper.getMetaVal(key, plus);

        if (unfixed === null) return unfixed;

        return Number.parseInt(unfixed) + fixNotNan;
    };

    globalThis.TRPGHelper.getMetaWithTagVal = (key, tag, plus) => {
        const from = dv.current()?.[key];

        let numRes = from
            ?.filter?.((s) => s?.includes(tag))
            ?.reduce?.(
                (pre, cur) =>
                    pre + Number.parseInt(cur?.replace?.(tag, "") ?? 0),
                0
            );

        if (plus && numRes !== null && numRes > 0) numRes = "+" + numRes;

        return numRes ?? from ?? null;
    };

    globalThis.TRPGHelper.getMetaWithTagValWithFix = (key, tag, plus) => {
        const fix = Number.parseInt(dv.current()?.[`${key}修正`] ?? 0);

        const fixNotNan = Number.isNaN(fix) ? 0 : fix;

        const fixWithTag = Number.parseInt(
            globalThis.TRPGHelper.getMetaWithTagVal(`${key}修正`, tag, plus) ??
                0
        );

        const fixWithTagNotNan = Number.isNaN(fix) ? 0 : fix;

        const unfixed = TRPGHelper.getMetaWithTagVal(key, tag, plus);

        if (unfixed === null) return unfixed;

        return Number.parseInt(unfixed) + fixNotNan + fixWithTagNotNan;
    };

    return;
})();
  • 那个比较复杂的自动表:
const Attributes = ["智力", "敏捷", "体质", "魅力", "力量", "感知"];

const getArrOrSingle = (key, tag) =>
    TRPGHelper.getMetaWithTagVal(key, tag, true) ?? 0;

const buyMapping = {
    [-4]: 7,
    [-2]: 8,
    [-1]: 9,
    [0]: 10,
    [1]: 11,
    [2]: 12,
    [3]: 13,
    [5]: 14,
    [7]: 15,
    [10]: 16,
    [13]: 17,
    [17]: 18,
};

const getFromBuy = (attr) =>
    buyMapping?.[Number.parseInt(getArrOrSingle("Buy点", attr[0]) ?? 0)];

const getFromOthers = (attr) => getArrOrSingle("属性修正", attr);

const getFromBorn = (attr) => getArrOrSingle("种族调整值", attr);

const getFix = (num) => Math.floor((Number.parseInt(num) - 10) / 2);

if (!globalThis?.TRPGHelper) globalThis.TRPGHelper = {};

globalThis.TRPGHelper.AttributeFixs = Object.fromEntries(
    Attributes.map((attr) => {
        let fixNum = getFix(
            Number.parseInt(getFromBuy(attr) ?? 0) +
                Number.parseInt(getFromBorn(attr) ?? 0) +
                Number.parseInt(getFromOthers(attr) ?? 0)
        );

        if (fixNum > 0) fixNum = "+" + fixNum;

        return [attr, fixNum];
    })
);

dv.table(
    [
        "属性",
        ...Attributes.map(
            (attr) =>
                `${attr}(${getFix(
                    Number.parseInt(getFromBuy(attr) ?? 0) +
                        Number.parseInt(getFromBorn(attr) ?? 0) +
                        Number.parseInt(getFromOthers(attr) ?? 0)
                )})`
        ),
    ],
    [
        [
            "初始调整",
            ...Attributes.map((attr) => getFromBuy(attr) ?? "错误buy点"),
        ],
        ["种族修正", ...Attributes.map((attr) => getFromBorn(attr) || "--")],
        ["其他修正", ...Attributes.map((attr) => getFromOthers(attr) || "--")],
        [
            "属性值",
            ...Attributes.map(
                (attr) =>
                    Number.parseInt(getFromBuy(attr) ?? 0) +
                    Number.parseInt(getFromBorn(attr) ?? 0) +
                    Number.parseInt(getFromOthers(attr) ?? 0)
            ),
        ],
    ]
);

不要挂到 global,把代码放 JS 文件传参复用行不呢。头部的查询用 dv.paragraph()

看代码你的数据应该是读取页面内其他的数据,所以我复制你的代码是 null。

1 个赞

大佬救救, 我想在 inline 的查询里用我的函数 (就像我现在的 $= TRPGHelper.getMetaWithTagVal("职业") 这样), view 这个函数有没有返回值呢, 如果有是什么?

主要是觉得写起来很麻烦很不优雅, 感觉 dataview 的设计可能不太时候我, 谢谢耐心解答, 今天尝试过了以后发现 react component 可以解决我的问题