mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-01-13 01:21:58 +00:00
feat: support prop.autorun
This commit is contained in:
parent
8f1a9de33b
commit
c0a523584e
@ -1,4 +1,4 @@
|
||||
import { obx, computed } from '@ali/lowcode-editor-core';
|
||||
import { obx, computed, autorun } from '@ali/lowcode-editor-core';
|
||||
import {
|
||||
isDOMText,
|
||||
isJSExpression,
|
||||
@ -155,17 +155,29 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
this._children = new NodeChildren(this as ParentalNode, this.initialChildren(children));
|
||||
this._children.interalInitParent();
|
||||
this.props.import(this.transformProps(props || {}), extras);
|
||||
this.setupAutoruns();
|
||||
}
|
||||
}
|
||||
|
||||
private transformProps(props: any): any {
|
||||
// FIXME! support PropsList
|
||||
const x = this.document.designer.transformProps(props, this, TransformStage.Init);
|
||||
|
||||
return x;
|
||||
return this.document.designer.transformProps(props, this, TransformStage.Init);
|
||||
// TODO: run transducers in metadata.experimental
|
||||
}
|
||||
|
||||
private autoruns?: Array<() => void>;
|
||||
private setupAutoruns() {
|
||||
const autoruns = this.componentMeta.getMetadata().experimental?.autoruns;
|
||||
if (!autoruns || autoruns.length < 1) {
|
||||
return;
|
||||
}
|
||||
this.autoruns = autoruns.map(item => {
|
||||
return autorun(() => {
|
||||
item.autorun(this.props.get(item.name, true) as any)
|
||||
}, true);
|
||||
});
|
||||
}
|
||||
|
||||
private initialChildren(children: any): NodeData[] {
|
||||
// FIXME! this is dirty code
|
||||
if (children == null) {
|
||||
@ -591,6 +603,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
if (this.isParental()) {
|
||||
this.children.purge();
|
||||
}
|
||||
this.autoruns?.forEach(dispose => dispose());
|
||||
this.props.purge();
|
||||
this.document.internalRemoveAndPurgeNode(this);
|
||||
}
|
||||
@ -608,7 +621,16 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
insertBefore(node: Node, ref?: Node) {
|
||||
this.children?.insert(node, ref ? ref.index : null);
|
||||
}
|
||||
insertAfter(node: Node, ref?: Node) {
|
||||
insertAfter(node: any, ref?: Node) {
|
||||
if (!isNode(node)) {
|
||||
if (node.getComponentName) {
|
||||
node = this.document.createNode({
|
||||
componentName: node.getComponentName(),
|
||||
});
|
||||
} else {
|
||||
node = this.document.createNode(node);
|
||||
}
|
||||
}
|
||||
this.children?.insert(node, ref ? ref.index + 1 : null);
|
||||
}
|
||||
getParent() {
|
||||
@ -687,6 +709,7 @@ export class Node<Schema extends NodeSchema = NodeSchema> {
|
||||
* @deprecated
|
||||
*/
|
||||
getSuitablePlace(node: Node, ref: any): any {
|
||||
// TODO:
|
||||
if (this.isRoot()) {
|
||||
return { container: this, ref };
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { obx, autorun, untracked, computed } from '@ali/lowcode-editor-core';
|
||||
import { Prop, IPropParent, UNSET } from './prop';
|
||||
import { Props } from './props';
|
||||
import { Node } from '../node';
|
||||
|
||||
export type PendingItem = Prop[];
|
||||
export class PropStash implements IPropParent {
|
||||
@ -15,8 +16,10 @@ export class PropStash implements IPropParent {
|
||||
return maps;
|
||||
}
|
||||
private willPurge: () => void;
|
||||
readonly owner: Node;
|
||||
|
||||
constructor(readonly props: Props, write: (item: Prop) => void) {
|
||||
this.owner = props.owner;
|
||||
this.willPurge = autorun(() => {
|
||||
if (this.space.size < 1) {
|
||||
return;
|
||||
|
||||
@ -4,7 +4,7 @@ import { uniqueId, isPlainObject, hasOwnProperty } from '@ali/lowcode-utils';
|
||||
import { PropStash } from './prop-stash';
|
||||
import { valueToSource } from './value-to-source';
|
||||
import { Props } from './props';
|
||||
import { SlotNode } from '../node';
|
||||
import { SlotNode, Node } from '../node';
|
||||
import { TransformStage } from '../transform-stage';
|
||||
|
||||
export const UNSET = Symbol.for('unset');
|
||||
@ -13,12 +13,14 @@ export type UNSET = typeof UNSET;
|
||||
export interface IPropParent {
|
||||
delete(prop: Prop): void;
|
||||
readonly props: Props;
|
||||
readonly owner: Node;
|
||||
}
|
||||
|
||||
export type ValueTypes = 'unset' | 'literal' | 'map' | 'list' | 'expression' | 'slot';
|
||||
|
||||
export class Prop implements IPropParent {
|
||||
readonly isProp = true;
|
||||
readonly owner: Node;
|
||||
|
||||
/**
|
||||
* @see SettingTarget
|
||||
@ -350,6 +352,7 @@ export class Prop implements IPropParent {
|
||||
key?: string | number,
|
||||
spread = false,
|
||||
) {
|
||||
this.owner = parent.owner;
|
||||
this.props = parent.props;
|
||||
if (value !== UNSET) {
|
||||
this.setValue(value);
|
||||
@ -613,6 +616,10 @@ export class Prop implements IPropParent {
|
||||
getProps() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
getNode() {
|
||||
return this.owner;
|
||||
}
|
||||
}
|
||||
|
||||
export function isProp(obj: any): obj is Prop {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react';
|
||||
import { isPlainObject } from '@ali/lowcode-utils';
|
||||
import { isI18nData, SettingTarget, InitialItem, FilterItem, isJSSlot, isJSExpression } from '@ali/lowcode-types';
|
||||
import { isI18nData, SettingTarget, InitialItem, FilterItem, isJSSlot, isJSExpression, AutorunItem } from '@ali/lowcode-types';
|
||||
import { untracked } from '@ali/lowcode-editor-core';
|
||||
|
||||
type Field = SettingTarget;
|
||||
|
||||
@ -290,19 +291,44 @@ export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollec
|
||||
};
|
||||
}
|
||||
|
||||
if (accessor && !slotName) {
|
||||
extraProps.getValue = (field: Field, fieldValue: any) => {
|
||||
return accessor.call(field, fieldValue);
|
||||
};
|
||||
if (!initialFn) {
|
||||
initialFn = accessor;
|
||||
if (!slotName) {
|
||||
if (accessor) {
|
||||
extraProps.getValue = (field: Field, fieldValue: any) => {
|
||||
return accessor.call(field, fieldValue);
|
||||
};
|
||||
}
|
||||
|
||||
if (sync || accessor) {
|
||||
collector.addAutorun({
|
||||
name,
|
||||
autorun: (field: Field) => {
|
||||
let fieldValue = untracked(() => field.getValue());
|
||||
if (accessor) {
|
||||
fieldValue = accessor.call(field, fieldValue)
|
||||
}
|
||||
if (sync) {
|
||||
fieldValue = sync.call(field, fieldValue);
|
||||
if (fieldValue !== undefined) {
|
||||
field.setValue(fieldValue);
|
||||
}
|
||||
} else {
|
||||
field.setValue(fieldValue);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (mutator) {
|
||||
extraProps.setValue = (field: Field, value: any) => {
|
||||
mutator.call(field, value, value);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const setterInitial = getInitialFromSetter(setter);
|
||||
|
||||
collector.addInitial({
|
||||
// FIXME! name should be "xxx.xxx"
|
||||
// FIXME! name could be "xxx.xxx"
|
||||
name: slotName || name,
|
||||
initial: (field: Field, currentValue: any) => {
|
||||
// FIXME! read from prototype.defaultProps
|
||||
@ -345,20 +371,6 @@ export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollec
|
||||
});
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
extraProps.autorun = (field: Field) => {
|
||||
const value = sync.call(field, field.getValue());
|
||||
if (value !== undefined) {
|
||||
field.setValue(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
if (mutator && !slotName) {
|
||||
extraProps.setValue = (field: Field, value: any) => {
|
||||
mutator.call(field, value, value);
|
||||
};
|
||||
}
|
||||
|
||||
if (slotName) {
|
||||
newConfig.name = slotName;
|
||||
if (!newConfig.title && slotTitle) {
|
||||
@ -396,7 +408,6 @@ export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollec
|
||||
let primarySetter: any;
|
||||
if (type === 'composite') {
|
||||
const initials: InitialItem[] = [];
|
||||
const filters: FilterItem[] = [];
|
||||
const objItems = items
|
||||
? upgradeConfigure(items,
|
||||
{
|
||||
@ -404,8 +415,17 @@ export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollec
|
||||
initials.push(item);
|
||||
},
|
||||
addFilter: (item) => {
|
||||
filters.push(item);
|
||||
}
|
||||
collector.addFilter({
|
||||
name: `${name}.${item.name}`,
|
||||
filter: item.filter,
|
||||
});
|
||||
},
|
||||
addAutorun: (item) => {
|
||||
collector.addAutorun({
|
||||
name: `${name}.${item.name}`,
|
||||
autorun: item.autorun,
|
||||
});
|
||||
},
|
||||
}
|
||||
)
|
||||
: [];
|
||||
@ -481,10 +501,12 @@ export function upgradePropConfig(config: OldPropConfig, collector: ConfigCollec
|
||||
|
||||
type AddInitial = (initialItem: InitialItem) => void;
|
||||
type AddFilter = (filterItem: FilterItem) => void;
|
||||
type AddAutorun = (autorunItem: AutorunItem) => void;
|
||||
|
||||
type ConfigCollector = {
|
||||
addInitial: AddInitial,
|
||||
addFilter: AddFilter,
|
||||
addInitial: AddInitial;
|
||||
addFilter: AddFilter;
|
||||
addAutorun: AddAutorun;
|
||||
}
|
||||
|
||||
function getInitialFromSetter(setter: any) {
|
||||
@ -750,6 +772,7 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
||||
|
||||
const initials: InitialItem[] = [];
|
||||
const filters: FilterItem[] = [];
|
||||
const autoruns: AutorunItem[] = [];
|
||||
const props = upgradeConfigure(configure || [],
|
||||
{
|
||||
addInitial: (item) => {
|
||||
@ -758,10 +781,14 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) {
|
||||
addFilter: (item) => {
|
||||
filters.push(item);
|
||||
},
|
||||
addAutorun: (item) => {
|
||||
autoruns.push(item);
|
||||
}
|
||||
}
|
||||
);
|
||||
experimental.initials = initials;
|
||||
experimental.filters = filters;
|
||||
experimental.autoruns = autoruns;
|
||||
|
||||
const supports: any = {};
|
||||
if (canUseCondition != null) {
|
||||
|
||||
@ -49,6 +49,11 @@ export interface FilterItem {
|
||||
name: string;
|
||||
filter: (target: SettingTarget, currentValue: any) => any;
|
||||
}
|
||||
export interface AutorunItem {
|
||||
name: string;
|
||||
autorun: (target: SettingTarget) => any;
|
||||
}
|
||||
|
||||
|
||||
export interface Experimental {
|
||||
context?: { [contextInfoName: string]: any };
|
||||
@ -57,8 +62,8 @@ export interface Experimental {
|
||||
transducers?: any; // ? should support
|
||||
initials?: InitialItem[];
|
||||
filters?: FilterItem[];
|
||||
autoruns?: AutorunItem[];
|
||||
callbacks?: Callbacks;
|
||||
// TODO: thinkof function
|
||||
initialChildren?: NodeData[] | ((target: SettingTarget) => NodeData[]);
|
||||
|
||||
// 样式 及 位置,handle上必须有明确的标识以便事件路由判断,或者主动设置事件独占模式
|
||||
@ -85,7 +90,7 @@ export interface Experimental {
|
||||
liveTextEditing?: LiveTextEditingConfig[];
|
||||
}
|
||||
|
||||
// thinkof Array
|
||||
// thinkof Array
|
||||
export interface LiveTextEditingConfig {
|
||||
propTarget: string;
|
||||
selector?: string;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user