diff --git a/src/dataSources/index.ts b/src/dataSources/index.ts new file mode 100644 index 000000000..1e32c5156 --- /dev/null +++ b/src/dataSources/index.ts @@ -0,0 +1,7 @@ +import { ItemManagerModule } from '../abstract/Module'; +import { DataSources } from './model/DataSources'; + +export default class DataSourceManager extends ItemManagerModule<{}, DataSources> { + storageKey = ''; + destroy(): void {} +} diff --git a/src/dataSources/model/DataRecord.ts b/src/dataSources/model/DataRecord.ts new file mode 100644 index 000000000..76c88711c --- /dev/null +++ b/src/dataSources/model/DataRecord.ts @@ -0,0 +1,23 @@ +import { keys } from 'underscore'; +import { Collection, Model } from '../../common'; +import { DataRecordProps } from '../types'; + +export class DataRecord extends Model { + // collection?: Collection; + + constructor(props: T, opts = {}) { + super(props, opts); + this.on('change', dr => { + const changed = dr.changedAttributes(); + keys(changed).forEach(prop => { + const eventKey = `${this.dataSource.id}.${this.id}.${prop}`; + console.log('changed', eventKey); + // em.trigger(eventKey); + }); + }); + } + + get dataSource() { + return (this.collection as any).dataSource; + } +} diff --git a/src/dataSources/model/DataRecords.ts b/src/dataSources/model/DataRecords.ts new file mode 100644 index 000000000..90b195747 --- /dev/null +++ b/src/dataSources/model/DataRecords.ts @@ -0,0 +1,15 @@ +import { Collection } from '../../common'; +import { DataRecordProps } from '../types'; +import { DataRecord } from './DataRecord'; +import { DataSource } from './DataSource'; + +export class DataRecords extends Collection { + dataSource: DataSource; + + constructor(models: DataRecord[] | Array, options: { dataSource: DataSource }) { + super(models, options); + this.dataSource = options.dataSource; + } +} + +DataRecords.prototype.model = DataRecord; diff --git a/src/dataSources/model/DataSource.ts b/src/dataSources/model/DataSource.ts new file mode 100644 index 000000000..9f334539b --- /dev/null +++ b/src/dataSources/model/DataSource.ts @@ -0,0 +1,15 @@ +import { Model } from '../../common'; +import { DataSourceProps } from '../types'; +import { DataRecords } from './DataRecords'; + +export class DataSource extends Model { + defaults() { + return { + records: [], + }; + } + + get records() { + return this.attributes.records as DataRecords; + } +} diff --git a/src/dataSources/model/DataSources.ts b/src/dataSources/model/DataSources.ts new file mode 100644 index 000000000..338aeb1c2 --- /dev/null +++ b/src/dataSources/model/DataSources.ts @@ -0,0 +1,4 @@ +import { Collection } from '../../common'; +import { DataSource } from './DataSource'; + +export class DataSources extends Collection {} diff --git a/src/dataSources/types.ts b/src/dataSources/types.ts new file mode 100644 index 000000000..26f3aaa97 --- /dev/null +++ b/src/dataSources/types.ts @@ -0,0 +1,22 @@ +import { ObjectAny } from '../common'; +import { DataRecord } from './model/DataRecord'; +import { DataRecords } from './model/DataRecords'; + +export interface DataSourceProps { + /** + * DataSource id. + */ + id: string; + + /** + * DataSource records. + */ + records?: DataRecords | DataRecord[] | DataRecordProps[]; +} + +export interface DataRecordProps extends ObjectAny { + /** + * Record id. + */ + id: string; +} diff --git a/src/editor/model/Editor.ts b/src/editor/model/Editor.ts index 3aac98110..a089b230b 100644 --- a/src/editor/model/Editor.ts +++ b/src/editor/model/Editor.ts @@ -3,7 +3,7 @@ import Backbone from 'backbone'; import $ from '../../utils/cash-dom'; import Extender from '../../utils/extender'; import { hasWin, isEmptyObj, wait } from '../../utils/mixins'; -import { AddOptions, Model, ObjectAny } from '../../common'; +import { AddOptions, Model, Collection, ObjectAny } from '../../common'; import Selected from './Selected'; import FrameView from '../../canvas/view/FrameView'; import Editor from '..'; @@ -104,6 +104,8 @@ export default class EditorModel extends Model { }; } + Model = Model; + Collection = Collection; __skip = false; defaultRunning = false; destroyed = false; diff --git a/src/utils/mixins.ts b/src/utils/mixins.ts index cb890dd9b..e0e86d259 100644 --- a/src/utils/mixins.ts +++ b/src/utils/mixins.ts @@ -7,6 +7,34 @@ import { ObjectAny } from '../common'; const obj: ObjectAny = {}; +const reEscapeChar = /\\(\\)?/g; +const rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; +const stringToPath = function (string: string) { + const result = []; + if (string.charCodeAt(0) === 46 /* . */) result.push(''); + string.replace(rePropName, (match: string, number, quote, subString) => { + result.push(quote ? subString.replace(reEscapeChar, '$1') : number || match); + return ''; + }); + return result; +}; + +function castPath(value: string | string[], object: ObjectAny) { + if (isArray(value)) return value; + return object.hasOwnProperty(value) ? [value] : stringToPath(value); +} + +export const get = (object: ObjectAny, path: string | string[], def: any) => { + const paths = castPath(path, object); + const length = paths.length; + let index = 0; + + while (object != null && index < length) { + object = object[`${paths[index++]}`]; + } + return (index && index == length ? object : undefined) ?? def; +}; + export const isBultInMethod = (key: string) => isFunction(obj[key]); export const normalizeKey = (key: string) => (isBultInMethod(key) ? `_${key}` : key);