UNPKG

zero-mvc

Version:

zeromvc是一种mvc设计模式。主要意义在于分离视图代码、逻辑代码和数据处理代码。

247 lines (246 loc) 7.52 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Model = exports.BaseModel = exports.Control = exports.View = exports.Zeromvc = exports.Command = void 0; class Command { } exports.Command = Command; class Zeromvc { constructor() { this.pool = new Map(); this.showViewList = []; this.instanceMap = new WeakMap(); if (Zeromvc.zeromvc != null) { Zeromvc.zeromvc.clear(); } Zeromvc.zeromvc = this; } emit(command, ...args) { return __awaiter(this, void 0, void 0, function* () { if (command instanceof Command) { let callbacks = this.pool.get(command.constructor); if (callbacks != null) { for (let index = 0; index < callbacks.length; index++) { const element = callbacks[index]; yield element(command); } } } else { let callbacks = this.pool.get(command); if (callbacks != null) { for (let index = 0; index < callbacks.length; index++) { const element = callbacks[index]; yield element(...args); } } } }); } on(command, callback) { let callbacks = this.pool.get(command); if (callbacks == null) { callbacks = []; this.pool.set(command, callbacks); } callbacks.push(callback); } getSingle(singleType) { let single; if (this.instanceMap.has(singleType)) { single = this.instanceMap.get(singleType); } else { single = new singleType(this); if (single._init != null) { single._init(); } this.instanceMap.set(singleType, single); } return single; } getModel(modelType) { return Model.getViewProxy(Zeromvc.zeromvc.getSingle(modelType)); } clear() { this.pool.clear(); } } exports.Zeromvc = Zeromvc; /** * 视图代码组织容器 */ class View { constructor() { this.bindList = []; } show() { this.bindList.forEach((item) => { Model.link(item.model, item.callback); }); } hide() { this.bindList.forEach((item) => { Model.unLink(item.model, item.callback); }); } getModel(modelType) { return Model.getViewProxy(Zeromvc.zeromvc.getSingle(modelType)); } emit(command, ...args) { return __awaiter(this, void 0, void 0, function* () { return Zeromvc.zeromvc.emit(command, ...args); }); } bind(model, target, prefix = "") { this.bindList.push({ model: model, target: target, prefix: prefix, callback: (key, value) => { const fn = target[prefix + key]; if (fn != null && typeof fn == "function") { fn.apply(target, [value]); } } }); } } exports.View = View; /** * 逻辑代码组织容器 */ class Control { getModel(modelType) { return Model.getControlProxy(Zeromvc.zeromvc.getSingle(modelType)); } emit(command, ...args) { return __awaiter(this, void 0, void 0, function* () { return Zeromvc.zeromvc.emit(command, ...args); }); } on(command, callback) { Zeromvc.zeromvc.on(command, callback); } } exports.Control = Control; class ModelTick { constructor(tickTime = 16) { this.tickTime = tickTime; this.tickList = []; setInterval(() => { this.tickList.forEach(element => { const keyPool = Model.tick(element); for (const key in keyPool) { const value = keyPool[key]; element.update(key, value); } }); this.tickList = []; }, this.tickTime); } } /** * 数据代码组织容器 */ class BaseModel { constructor() { this.pool = new Set(); } static link(model, value) { if (!model.pool.has(value)) { model.pool.add(value); } } static unLink(model, value) { if (model.pool.has(value)) { model.pool.delete(value); } } start() { } update(key, ...args) { this.pool.forEach((item) => { item(key, ...args); }); } _init() { this.start(); } } exports.BaseModel = BaseModel; /** * 数据代码组织容器 */ class Model extends BaseModel { constructor() { super(...arguments); this.updateKeyPool = {}; } static getControlProxy(value) { return value.controlProxy; } static getViewProxy(value) { return value.viewProxy; } static tick(value) { const out = value.updateKeyPool; value.updateKeyPool = {}; return out; } start() { } _init() { this.controlProxy = new Proxy(this, { set: (target, key, value, receiver) => { if (target[key] != value) { target[key] = value; if (typeof key == "string" && key.charAt(0) != "_") { this.updateKeyPool[key] = value; Model.modelTick.tickList.push(target); } } return true; }, get: (target, key) => { const value = target[key]; if (typeof value == "function" && typeof key == "string" && key.charAt(0) != "_") { return (...args) => { value.apply(target, args); this.updateKeyPool[key] = null; Model.modelTick.tickList.push(target); }; } else { return value; } } }); this.viewProxy = new Proxy(this, { set: (target, key, value, receiver) => { target[key] = value; throw new Error("在视图(View)中里不能直接修改模型(Model)的值"); }, get: (target, key) => { const value = target[key]; if (typeof value == "function") { throw new Error("在视图(View)中里不能直接调用模型(Model)的方法"); } else { return value; } } }); super._init(); } } exports.Model = Model; Model.modelTick = new ModelTick();