UNPKG

@mlightcad/common

Version:

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://img.shields.io/npm/v/@mlightcad/common.svg)](https://www.npmjs.com/package/@mlightcad/common)

150 lines 6.05 kB
/** * @fileoverview Object model implementation for the AutoCAD Common library. * * This module provides a reactive object model with attribute management, * change tracking, and event notification. Inspired by Backbone.js Model * but with TypeScript support and reduced dependencies. * * @module AcCmObject * @version 1.0.0 */ import { AcCmEventManager } from './AcCmEventManager'; export type AcCmAttributes = Record<string, any>; /** * Options to set attributes of one `AcCmObject` instance */ export interface AcCmObjectOptions { silent?: boolean | undefined; unset?: boolean | undefined; } export type AcCmStringKey<T> = keyof T & string; /** * Interface to define arguments of changed event of one `AcCmObject` instance */ export interface AcCmObjectChangedEventArgs<T extends AcCmAttributes> { object: AcCmObject<T>; options?: AcCmObjectOptions; } /** * Interface to define arguments of attribute changed event of one `AcCmObject` instance */ export interface AcCmObjectAttributeChangedEventArgs<T extends AcCmAttributes> extends AcCmObjectChangedEventArgs<T> { attrName?: string; attrValue?: any; } /** * This class is used to store attributes of one data model. It has the following benifits. * - Get notification when value of one attributes is changed * - Have one `changed` property to store all of changed values * - Store all of states of one model in one key/value object and make it is easy to serialize/deserialize model and model changes * * Actually implementation of this class is based on class Model in Backbone.js. However, Model class in Backbone * is too heavy. So we implement it again based on source code of class Model in Backbone.js. Morever, we want to * keep our library with less external dependencies and don't want to introduce depenedency on Backbone.js. */ export declare class AcCmObject<T extends AcCmAttributes = any> { attributes: Partial<T>; changed: Partial<T>; readonly events: { attrChanged: AcCmEventManager<AcCmObjectAttributeChangedEventArgs<T>>; modelChanged: AcCmEventManager<AcCmObjectChangedEventArgs<T>>; }; private _changing; private _previousAttributes; private _pending; /** * Create one object to store attributes. For performance reason, values of attributes passed to constructor * will not be cloned to `attributes` property. So it means that value of `attributes` property in this object * is just a reference to arguments `attributes` passed to constructor. * @param attributes Input attributes to store in this object */ constructor(attributes?: Partial<T>, defaultAttrs?: Partial<T>); /** * Gets the value of an attribute. * * For strongly-typed access to attributes, use the `get` method privately in public getter properties. * * @template A - The key type extending string keys of T. * @param {A} key - The attribute key to retrieve. * @returns {T[A] | undefined} The attribute value or undefined if not set. * * @example * ```typescript * // Get a single attribute value * const name = obj.get('name') * const visible = obj.get('visible') * * // Check if attribute exists * if (obj.get('name') !== undefined) { * console.log('Name is set') * } * * // For strongly-typed subclasses * get name(): string { * return super.get("name") * } * ``` */ get<A extends AcCmStringKey<T>>(key: A): T[A] | undefined; /** * Sets one or more attributes on the object. * * For strongly-typed assignment of attributes, use the `set` method privately in public setter properties. * Triggers change events unless the `silent` option is specified. * * @template A - The key type extending string keys of T. * @param {A | Partial<T>} key - The attribute key or an object of key-value pairs. * @param {T[A] | AcCmObjectOptions} [val] - The value to set or options when key is an object. * @param {AcCmObjectOptions} [options] - Options for the set operation. * @returns {this} The current instance for method chaining. * * @example * ```typescript * // Set a single attribute * obj.set('name', 'MyEntity') * * // Set multiple attributes * obj.set({ name: 'MyEntity', visible: true }) * * // Set with options * obj.set('name', 'MyEntity', { silent: true }) * * // Unset an attribute * obj.set('name', undefined, { unset: true }) * * // For strongly-typed subclasses * set name(value: string) { * super.set("name", value) * } * ``` */ set<A extends AcCmStringKey<T>>(key: A, val?: T[A], options?: AcCmObjectOptions): this; set(key: Partial<T>, options?: AcCmObjectOptions): this; has(key: AcCmStringKey<T>): boolean; /** * Determine if the model has changed since the last `"change"` event. * If you specify an attribute name, determine if that attribute has changed. */ hasChanged(key?: AcCmStringKey<T>): boolean; /** * Return an object containing all the attributes that have changed. Useful for determining what parts * of a view need to be updated and/or what attributes need to be persisted to the server. * * Unset attributes will be set to undefined. You can also pass an attributes object to diff against * the model, determining if there *would be* a change. */ changedAttributes(diff?: Partial<T>): Partial<T>; /** * Get the previous value of an attribute, recorded at the time the last `"change"` event was fired. */ previous<A extends AcCmStringKey<T>>(key: A): T[A] | null | undefined; /** * Get all of the attributes of the model at the time of the previous `"change"` event. */ previousAttributes(): Partial<T>; /** * Create a new model with identical attributes to this one. */ clone(): AcCmObject<T>; } //# sourceMappingURL=AcCmObject.d.ts.map