Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 37 additions & 8 deletions packages/canvas/render/src/application-function/global-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,43 @@ export function useGlobalState() {
watchEffect(() => {
reset(stores)
globalState.value.forEach(({ id, state = {}, getters = {} }) => {
const computedGetters = Object.keys(getters).reduce(
(acc, key) => ({
...acc,
[key]: new Func('return ' + getters[key])().call(acc, state) // parseData(getters[key], null, acc)?.call?.(acc, state) //理论上不应该走parseData, unibuy代码遗留
}),
{}
)
stores[id] = { ...state, ...computedGetters }
const hasGetters = Object.keys(getters).length > 0

if (Array.isArray(state)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以给一下相关的场景用例数据嘛?我们结合来评估一下,麻烦啦~

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原来的代码,新建一个应用状态,如: testList: ["One", "Two", "Three", "Four"],变量列表中会展示四个变量: testList.0、testList.1、testList.2、testList.3
如果是字符串,如 demo: "Hello",变量列表会得到 demo.0/demo.1/……

if (!hasGetters) {
stores[id] = [...state]
} else {
const computedGetters = {}
Object.keys(getters).forEach((key) => {
try {
computedGetters[key] = new Func('return ' + getters[key])().call(computedGetters, state)
} catch (error) {
computedGetters[key] = undefined
}
})

const arrayWithGetters = [...state]
Object.assign(arrayWithGetters, computedGetters)
stores[id] = arrayWithGetters
}
} else if (typeof state !== 'object' || state === null) {
Copy link
Copy Markdown
Member

@chilingling chilingling Mar 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我们将全局状态的 state 限制为 plain object 会不会好一点?
因为我们这里的实现是基于 pinia,但是 pinia 要求我们 state 返回一个初始状态:

https://pinia.vuejs.org/zh/core-concepts/state.html

截屏2025-03-17 14 56 24

截屏2025-03-17 14 59 05

stores[id] = state
} else {
if (!hasGetters) {
stores[id] = { ...state }
} else {
const computedGetters = {}
Object.keys(getters).forEach((key) => {
try {
computedGetters[key] = new Func('return ' + getters[key])().call(computedGetters, state)
} catch (error) {
computedGetters[key] = undefined
}
})

stores[id] = Object.assign({}, state, computedGetters)
}
}
})
})
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,14 +503,8 @@ export default {
state.variables = {}

const stores = useResource().appSchemaState.globalState
stores.forEach(({ id, state: storeState = {}, getters = {} }) => {
const loadProp = (prop) => {
const propBinding = `${id}.${prop}`
state.variables[propBinding] = propBinding
}

Object.keys(storeState).forEach(loadProp)
Object.keys(getters).forEach(loadProp)
stores.forEach(({ id, state: _storeState = {}, _getters = {} }) => {
state.variables[id] = id
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

【bug 场景】:
当全局应用状态设置为数组时,绑定变量弹窗处分割的状态不正确。
截屏2025-03-17 14 18 53
截屏2025-03-17 14 20 53

【origin 状态分割的场景】
应用的状态可能有很多的字段,为了方便用户快速绑定对应的字段,这里做了优化。
比如一个应用状态可能是 object,有很多的字段,可能还有 getter:

截屏2025-03-17 14 24 50
截屏2025-03-17 14 26 26

所以这里仅特殊处理一下数组的场景会好一点?

})
} else if (item.id === 'loop') {
state.bindPrefix = ''
Expand Down
4 changes: 2 additions & 2 deletions packages/plugins/materials/src/composable/useResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ const fetchAppState = async () => {

appSchemaState.bridge = appData.bridge
appSchemaState.utils = appData.utils
appSchemaState.isDemo = appData.meta?.is_demo
appSchemaState.globalState = appData?.meta.global_state
appSchemaState.isDemo = appData.meta?.isDemo || appData.meta?.is_demo
appSchemaState.globalState = appData?.meta.globalState || appData?.meta.global_state

// 词条语言为空时使用默认的语言
const defaultLocales = [
Expand Down
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

原代码中,直接赋值为 store(),出码后,变量的值变成了 store 实例,而不是所需的变量值

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const useStores = () => {
const stores = {}

Object.values({ ...useDefinedStores }).forEach((store) => {
stores[store.$id] = store()
stores[store.$id] = store().$state
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

请问这里改成 $state 是有什么 bug 场景不满足吗?

这里应该不仅仅只赋值 store 的 state。
因为我们要允许用户从 this.stores.storeName 读取 state 或者是 action 或者是 gettter state。
比如:

  • this.stores.test.name 读取 state
  • this.stores.test.fullName 读取 getterState
  • this.stores.test.setName 拿到 stores 的 action

})

return stores
Expand Down