mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2025-04-12 21:50:23 +08:00
add arrayState Trait
This commit is contained in:
parent
a2860b1ea9
commit
16f07c20f9
@ -58,7 +58,7 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'core/v1/state',
|
||||
type: 'core/v1/arrayState',
|
||||
properties: {
|
||||
key: 'listData',
|
||||
initialValue: listdata,
|
||||
@ -208,10 +208,11 @@
|
||||
event: 'click',
|
||||
componentId: 'root',
|
||||
method: {
|
||||
name: 'setValue',
|
||||
name: 'deleteItemById',
|
||||
parameters: {
|
||||
key: 'listData',
|
||||
value: `{{ (root.listData || []).filter((item) => item.id !== $listItem.id)}}`,
|
||||
itemIdKey: 'id',
|
||||
itemId: '{{ $listItem.id }}',
|
||||
},
|
||||
},
|
||||
wait: {},
|
||||
|
@ -12,7 +12,7 @@ import { ImplWrapper, resolveAppComponents } from '../../App';
|
||||
import { mapValuesDeep, maskedEval } from '../../store';
|
||||
import { values } from 'lodash';
|
||||
import { parseType } from '../../util-methods';
|
||||
import { LIST_ITEM_EXP } from '../../constants';
|
||||
import { LIST_ITEM_EXP, LIST_ITEM_INDEX_EXP } from '../../constants';
|
||||
|
||||
export function parseTypeComponents(
|
||||
c: Application['spec']['components'][0]
|
||||
@ -52,7 +52,10 @@ const List: ComponentImplementation<{
|
||||
{ parsedtemplete },
|
||||
({ value, key }) => {
|
||||
if (typeof value === 'string') {
|
||||
return maskedEval(value, true, { [LIST_ITEM_EXP]: listItem });
|
||||
return maskedEval(value, true, {
|
||||
[LIST_ITEM_EXP]: listItem,
|
||||
[LIST_ITEM_INDEX_EXP]: i,
|
||||
});
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
export const LIST_ITEM_EXP = '$listItem';
|
||||
export const LIST_ITEM_INDEX_EXP = '$i';
|
||||
|
@ -29,6 +29,7 @@ import ChakraUIVStack from './components/chakra-ui/VStack';
|
||||
/* --- lab --- */
|
||||
import LabEditor from './components/lab/Editor';
|
||||
// traits
|
||||
import CoreArrayState from './traits/core/arrayState';
|
||||
import CoreState from './traits/core/state';
|
||||
import CoreEvent from './traits/core/event';
|
||||
import CoreSlot from './traits/core/slot';
|
||||
@ -150,6 +151,7 @@ registry.registerComponent(LabEditor);
|
||||
registry.registerComponent(CoreRouter);
|
||||
|
||||
registry.registerTrait(CoreState);
|
||||
registry.registerTrait(CoreArrayState);
|
||||
registry.registerTrait(CoreEvent);
|
||||
registry.registerTrait(CoreSlot);
|
||||
registry.registerTrait(CoreHidden);
|
||||
|
@ -3,7 +3,7 @@ import dayjs from 'dayjs';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import { reactive } from '@vue/reactivity';
|
||||
import { watch } from '@vue-reactivity/watch';
|
||||
import { LIST_ITEM_EXP } from './constants';
|
||||
import { LIST_ITEM_EXP, LIST_ITEM_INDEX_EXP } from './constants';
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
@ -50,7 +50,11 @@ function parseExpression(str: string, parseListItem = false): ExpChunk[] {
|
||||
};
|
||||
// $listItem cannot be evaled in stateStore, so don't mark it as dynamic
|
||||
// unless explicitly pass parseListItem as true
|
||||
if (!parseListItem && substr.includes(LIST_ITEM_EXP)) {
|
||||
if (
|
||||
(substr.includes(LIST_ITEM_EXP) ||
|
||||
substr.includes(LIST_ITEM_INDEX_EXP)) &&
|
||||
!parseListItem
|
||||
) {
|
||||
chunk.expression = `{{${substr}}}`;
|
||||
chunk.isDynamic = false;
|
||||
}
|
||||
|
110
packages/runtime/src/traits/core/arrayState.tsx
Normal file
110
packages/runtime/src/traits/core/arrayState.tsx
Normal file
@ -0,0 +1,110 @@
|
||||
import { createTrait } from '@meta-ui/core';
|
||||
import { Static, Type } from '@sinclair/typebox';
|
||||
import { TraitImplementation } from '../../registry';
|
||||
import { stateStore } from '../../store';
|
||||
|
||||
const HasInitializedMap = new Map<string, boolean>();
|
||||
|
||||
type KeyValue = { key: string; value: unknown };
|
||||
|
||||
const ArrayStateTrait: TraitImplementation<{
|
||||
key: Static<typeof KeyPropertySchema>;
|
||||
initialValue: Static<typeof InitialValuePropertySchema>;
|
||||
}> = ({ key, initialValue, componentId, mergeState, subscribeMethods }) => {
|
||||
const hashId = `#${componentId}@${key}`;
|
||||
let hasInitialized = HasInitializedMap.get(hashId);
|
||||
|
||||
if (!hasInitialized) {
|
||||
mergeState({ [key]: initialValue });
|
||||
|
||||
const upperCaseKey = capitalizeFirstLetter(key);
|
||||
const methods = {
|
||||
setArray({ key, value }: KeyValue) {
|
||||
mergeState({ [key]: value });
|
||||
},
|
||||
deleteItemByIndex({ key, index }: { key: string; index: number }) {
|
||||
const _arr = [...stateStore[componentId][key]];
|
||||
_arr.splice(index, 1);
|
||||
mergeState({ [key]: _arr });
|
||||
},
|
||||
deleteItemById({
|
||||
key,
|
||||
itemIdKey,
|
||||
itemId,
|
||||
}: {
|
||||
key: string;
|
||||
itemIdKey: string;
|
||||
itemId: string;
|
||||
}) {
|
||||
const _arr = [...stateStore[componentId][key]].filter(item => {
|
||||
return item[itemIdKey] !== itemId;
|
||||
});
|
||||
mergeState({ [key]: _arr });
|
||||
},
|
||||
};
|
||||
subscribeMethods(methods);
|
||||
HasInitializedMap.set(hashId, true);
|
||||
}
|
||||
|
||||
return {
|
||||
props: null,
|
||||
};
|
||||
};
|
||||
|
||||
function capitalizeFirstLetter(str: string) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
const KeyPropertySchema = Type.String();
|
||||
const InitialValuePropertySchema = Type.Array(Type.Any());
|
||||
|
||||
export default {
|
||||
...createTrait({
|
||||
version: 'core/v1',
|
||||
metadata: {
|
||||
name: 'arrayState',
|
||||
description: 'add array state to component',
|
||||
},
|
||||
spec: {
|
||||
properties: [
|
||||
{
|
||||
name: 'key',
|
||||
...KeyPropertySchema,
|
||||
},
|
||||
{
|
||||
name: 'initialValue',
|
||||
...InitialValuePropertySchema,
|
||||
},
|
||||
],
|
||||
state: Type.Any(),
|
||||
methods: [
|
||||
{
|
||||
name: 'setArray',
|
||||
parameters: Type.Object({
|
||||
key: Type.String(),
|
||||
value: Type.Array(Type.Any()),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'deleteItemByIndex',
|
||||
parameters: Type.Object({
|
||||
key: Type.String(),
|
||||
index: Type.Integer(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'deleteItemById',
|
||||
parameters: Type.Object({
|
||||
key: Type.String(),
|
||||
itemIdKey: Type.String(),
|
||||
itemId: Type.String(),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'reset',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
impl: ArrayStateTrait,
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user