From 50b9158ce763aaf1f061a9de2b4bf160f49fb003 Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Tue, 16 Jul 2019 21:05:48 +0800 Subject: [PATCH] use proxy to intercept view's property --- js-framework/index.ts | 4 ++-- js-framework/package-lock.json | 10 +++++++++- js-framework/package.json | 7 +++++-- js-framework/tsconfig.json | 2 +- js-framework/util/types.ts | 21 --------------------- js-framework/view/view.ts | 30 ++++++++++++++++++++++-------- 6 files changed, 39 insertions(+), 35 deletions(-) diff --git a/js-framework/index.ts b/js-framework/index.ts index 88e71e07..9fd0d81d 100644 --- a/js-framework/index.ts +++ b/js-framework/index.ts @@ -12,6 +12,6 @@ v.config = { } console.log(v.toModel()) -const layout = new Text - +const layout = new VLayout +layout.space = 10 console.log(layout.toModel()) diff --git a/js-framework/package-lock.json b/js-framework/package-lock.json index cb380b79..e46d5280 100644 --- a/js-framework/package-lock.json +++ b/js-framework/package-lock.json @@ -1,5 +1,13 @@ { "name": "hego-jsframework", "version": "0.1.0", - "lockfileVersion": 1 + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" + } + } } diff --git a/js-framework/package.json b/js-framework/package.json index 5da1599a..5211f3a3 100644 --- a/js-framework/package.json +++ b/js-framework/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "dev": "tsc -p .&& node ../build/index.js" + "dev": "tsc -p .&& node ./build/index.js" }, "repository": { "type": "git", @@ -16,5 +16,8 @@ "bugs": { "url": "https://github.com/penfeizhou/hego/issues" }, - "homepage": "https://github.com/penfeizhou/hego#readme" + "homepage": "https://github.com/penfeizhou/hego#readme", + "dependencies": { + "reflect-metadata": "^0.1.13" + } } \ No newline at end of file diff --git a/js-framework/tsconfig.json b/js-framework/tsconfig.json index 0a939879..c3efcf59 100644 --- a/js-framework/tsconfig.json +++ b/js-framework/tsconfig.json @@ -13,7 +13,7 @@ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - "outDir": "../build/", /* Redirect output structure to the directory. */ + "outDir": "build/", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ diff --git a/js-framework/util/types.ts b/js-framework/util/types.ts index 5ef2a21f..772efba9 100644 --- a/js-framework/util/types.ts +++ b/js-framework/util/types.ts @@ -1,24 +1,3 @@ -export interface IWatcher { - onPropertyChanged(propKey: string, oldV: any, newV: any): void -} - - -export function Property(target: IWatcher, propKey: string) { - const key = Symbol(propKey) - Reflect.defineProperty(target, propKey, { - configurable: false, - enumerable: true, - get: () => { - return Reflect.get(target, key) - }, - set: (v: any) => { - const oldV = Reflect.get(target, key) - Reflect.set(target, key, v) - target.onPropertyChanged(propKey, oldV, v) - } - }) -} - export interface Modeling { toModel(): Model } diff --git a/js-framework/view/view.ts b/js-framework/view/view.ts index 78d2bb0a..0a8b0b3f 100644 --- a/js-framework/view/view.ts +++ b/js-framework/view/view.ts @@ -1,8 +1,12 @@ import { Color, GradientColor } from "../util/color" -import { Property, IWatcher, Modeling, Model } from "../util/types"; +import { Modeling, Model } from "../util/types"; +import "reflect-metadata" +export function Property(target: Object, propKey: string) { + Reflect.defineMetadata(propKey, true, target) +} -export abstract class View implements IWatcher, Modeling { +export abstract class View implements Modeling { @Property width: number = 0 @@ -29,7 +33,21 @@ export abstract class View implements IWatcher, Modeling { @Property alpha?: number - + constructor() { + return new Proxy(this, { + get: (target, p) => { + return Reflect.get(target, p) + }, + set: (target, p, v) => { + const oldV = Reflect.get(target, p) + const ret = Reflect.set(target, p, v) + if (Reflect.getMetadata(p, target)) { + this.onPropertyChanged(p.toString(), oldV, v) + } + return ret + } + }) + } /** Anchor start*/ get left() { return this.x @@ -62,13 +80,9 @@ export abstract class View implements IWatcher, Modeling { } /** Anchor end*/ - __dirty_props__?: { [index: string]: Model | undefined } + __dirty_props__: { [index: string]: Model | undefined } = {} onPropertyChanged(propKey: string, oldV: Model, newV: Model): void { - //console.log(`onPropertyChanged:${propKey},old value is ${oldV},new value is ${newV}`) - if (this.__dirty_props__ === undefined) { - this.__dirty_props__ = {} - } if (newV instanceof Object && Reflect.has(newV, 'toModel') && Reflect.get(newV, 'toModel') instanceof Function) {