update array properties

This commit is contained in:
Bowen Tan 2022-01-11 13:51:49 +08:00
parent b5cbcd1666
commit ffc4f5377d
6 changed files with 135 additions and 18 deletions

View File

@ -5,7 +5,9 @@ import {
SlotName,
TraitType,
} from '../../src/AppModel/IAppModel';
import { AppSchema } from './mock';
import { AppSchema, EventHanlderMockSchema } from './mock';
import { produce } from 'immer';
import { get } from 'lodash-es';
describe('ComponentModel test', () => {
it('compute component property', () => {
@ -52,6 +54,23 @@ describe('update component property', () => {
});
});
describe('update event trait handlers(array) property', () => {
const appModel = new AppModel(EventHanlderMockSchema);
const button1 = appModel.getComponentById('button1' as any);
const oldHandlers = button1.traits[0].rawProperties.handlers;
const newHandlers = produce(oldHandlers, draft => {
draft[1].method.parameters.value = 'hello';
});
button1.updateTraitProperties(button1.traits[0].id, { handlers: newHandlers });
const newSchema = appModel.toSchema();
it('update trait array properties', () => {
expect(
get(newSchema[0].traits[0].properties, 'handlers[1].method.parameters.value')
).toEqual('hello');
});
});
describe('append to another component', () => {
const appModel = new AppModel(AppSchema.spec.components);
const origin = appModel.toSchema();

View File

@ -16,15 +16,30 @@ describe('Field test', () => {
});
it('parse object property', () => {
const field = new FieldModel({raw: '{{input.value}}', format: 'md'});
const field = new FieldModel({ raw: '{{input.value}}', format: 'md' });
expect(field.isDynamic).toEqual(false);
expect(field.refs).toEqual([]);
expect(field.rawValue).toEqual({raw: '{{input.value}}', format: 'md'});
expect(field.getProperty('raw').value).toEqual('{{input.value}}');
expect(field.rawValue).toEqual({ raw: '{{input.value}}', format: 'md' });
expect(field.getProperty('raw').rawValue).toEqual('{{input.value}}');
expect(field.getProperty('raw').isDynamic).toEqual(true);
expect(field.getProperty('raw').refs).toEqual(['input']);
expect(field.getProperty('format').value).toEqual('md');
expect(field.getProperty('format').rawValue).toEqual('md');
expect(field.getProperty('format').isDynamic).toEqual(false);
expect(field.getProperty('format').refs).toEqual([]);
});
it('parse array property', () => {
const field = new FieldModel({ data: [1, '{{fetch.data}}'] });
expect(field.isDynamic).toEqual(false);
expect(field.refs).toEqual([]);
expect(field.rawValue).toEqual({ data: [1, '{{fetch.data}}'] });
expect(field.getProperty('data').rawValue).toEqual([1, '{{fetch.data}}']);
expect(field.getProperty('data').isDynamic).toEqual(false);
expect(field.getProperty('data').refs).toEqual([]);
expect(field.getProperty('data').getProperty(0).rawValue).toEqual(1);
expect(field.getProperty('data').getProperty(0).isDynamic).toEqual(false);
expect(field.getProperty('data').getProperty(1).rawValue).toEqual('{{fetch.data}}');
expect(field.getProperty('data').getProperty(1).isDynamic).toEqual(true);
expect(field.getProperty('data').getProperty(1).refs).toEqual(['fetch']);
});
});

View File

@ -148,3 +148,40 @@ export const DuplicatedIdSchema: ComponentSchema[] = [
traits: [],
},
];
export const EventHanlderMockSchema: ComponentSchema[] = [
{
id: 'button1',
type: 'chakra_ui/v1/button',
properties: {},
traits: [
{
type: 'core/v1/event',
properties: {
handlers: [
{
type: 'onClick',
componentId: 'input1',
method: {
name: 'setInputValue',
parameters: {
value: '666',
},
},
},
{
type: 'onClick',
componentId: 'input2',
method: {
name: 'setInputValue',
parameters: {
value: '666',
},
},
},
],
},
},
],
},
];

View File

@ -74,6 +74,45 @@ export const ComponentWrongPropertyExpressionSchema: ComponentSchema[] = [
properties: { spacing: '24px', align: '{{input.value}}' },
traits: [],
},
{
id: 'button1',
type: 'chakra_ui/v1/button',
properties: {
text: {
raw: 'hello',
format: 'md',
},
},
traits: [
{
type: 'core/v1/event',
properties: {
handlers: [
{
type: 'onClick',
componentId: 'button1',
method: {
name: 'click',
parameters: {
value: '666',
},
},
},
{
type: 'onClick',
componentId: 'dialog1',
method: {
name: 'click',
parameters: {
value: '666',
},
},
},
],
},
},
],
},
];
export const TraitInvalidSchema: ComponentSchema[] = [

View File

@ -263,7 +263,9 @@ export class ComponentModel implements IComponentModel {
const trait = this.traits.find(t => t.id === traitId);
if (!trait) return;
for (const property in properties) {
trait.properties[property].update(properties[property]);
if (trait.properties[property]) {
trait.updateProperty(property, properties[property])
}
trait._isDirty = true;
}
this._isDirty = true;

View File

@ -14,7 +14,7 @@ const regExp = new RegExp('.*{{.*}}.*');
isPlainObject
export class FieldModel implements IFieldModel {
private value: unknown | Record<string, IFieldModel>;
private value: unknown | Array<IFieldModel> | Record<string, IFieldModel>;
isDynamic = false;
refs: Array<ComponentId | ModuleId> = [];
@ -23,10 +23,11 @@ export class FieldModel implements IFieldModel {
}
update(value: unknown) {
if (isObject(value) && !isArray(value)) {
if (isObject(value)) {
if (!isObject(this.value)) {
this.value = {};
this.value = isArray(value) ? [] : {}
}
for (const key in value) {
const val = (value as Record<string, unknown>)[key];
const _thisValue = this.value as Record<string, IFieldModel>;
@ -43,24 +44,28 @@ export class FieldModel implements IFieldModel {
this.parseReferences();
}
getProperty(key?: string) {
if (!key) {
getProperty(key?: string | number) {
if (key === undefined) {
return this.value;
}
if (key && typeof this.value === 'object') {
if (key !== undefined && typeof this.value === 'object') {
return (this.value as any)[key];
}
return undefined;
}
get rawValue() {
if (isObject(this.value) && !isArray(this.value) ) {
const _thisValue = this.value as Record<string, IFieldModel>;
const res: Record<string, any> = {};
for (const key in _thisValue) {
res[key] = _thisValue[key].rawValue;
if (isObject(this.value)) {
if (isArray(this.value)) {
return this.value.map((field) => field.rawValue)
} else {
const _thisValue = this.value as Record<string, IFieldModel>;
const res: Record<string, any> = {};
for (const key in _thisValue) {
res[key] = _thisValue[key].rawValue;
}
return res;
}
return res;
}
return this.value;
}