UNPKG

terriajs

Version:

Geospatial data visualization platform.

69 lines (60 loc) 2.22 kB
import { computed } from "mobx"; import ModelTraits from "../../Traits/ModelTraits"; import Stratified from "../../Traits/Stratified"; import TraitsConstructor from "../../Traits/TraitsConstructor"; import ModelPropertiesFromTraits from "./ModelPropertiesFromTraits"; /** * Adds a set of traits to a model. The values of the traits will be derived * from the model's strata. * @param model The model class or instance. * @param Traits The traits class. * @returns The original model, now modified to add the added traits. */ export default function addModelStrataView< T extends TraitsConstructor<ModelTraits> >( /* TODO: Use a more specific type than "Function". */ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type model: Stratified<InstanceType<T>> | Function, Traits: T ): ModelPropertiesFromTraits<InstanceType<T>>; export default function addModelStrataView< T extends TraitsConstructor<ModelTraits> >(model: any, Traits: T): ModelPropertiesFromTraits<InstanceType<T>> { const traits = Traits.traits; const decorators: { [id: string]: PropertyDecorator } = {}; const propertyTarget = typeof model === "function" ? model.prototype : model; const traitsInstance: any = new Traits(); Object.keys(traits).forEach((traitName) => { const trait = traits[traitName]; const defaultValue = traitsInstance[traitName]; Object.defineProperty(propertyTarget, traitName, { get: function () { const value = trait.getValue(this); return value === undefined ? defaultValue : value; }, enumerable: true, configurable: true }); decorators[traitName] = trait.decoratorForFlattened || computed; }); decorate(model, decorators); return model; } /** * Decorate the target class. * * Note that we assume that the class constructor calls `makeObservable(this)` * to correctly setup the mobx properties. * * @param target Target class to decorate * @param decorators Properties of the class that must be decorated */ function decorate( target: any, decorators: { [id: string]: PropertyDecorator } ) { Object.entries(decorators).forEach(([prop, decorator]) => { decorator(target.prototype, prop); }); }