zero-mvc
Version:
zeromvc是一种mvc设计模式。主要意义在于分离视图代码、逻辑代码和数据处理代码。
247 lines (246 loc) • 7.52 kB
JavaScript
;
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();