use proxy to intercept view's property

This commit is contained in:
pengfei.zhou 2019-07-16 21:05:48 +08:00
parent de08866eb4
commit 50b9158ce7
6 changed files with 39 additions and 35 deletions

View File

@ -12,6 +12,6 @@ v.config = {
} }
console.log(v.toModel()) console.log(v.toModel())
const layout = new Text const layout = new VLayout
layout.space = 10
console.log(layout.toModel()) console.log(layout.toModel())

View File

@ -1,5 +1,13 @@
{ {
"name": "hego-jsframework", "name": "hego-jsframework",
"version": "0.1.0", "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=="
}
}
} }

View File

@ -5,7 +5,7 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"dev": "tsc -p .&& node ../build/index.js" "dev": "tsc -p .&& node ./build/index.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -16,5 +16,8 @@
"bugs": { "bugs": {
"url": "https://github.com/penfeizhou/hego/issues" "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"
}
} }

View File

@ -13,7 +13,7 @@
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single 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. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */ // "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */

View File

@ -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 { export interface Modeling {
toModel(): Model toModel(): Model
} }

View File

@ -1,8 +1,12 @@
import { Color, GradientColor } from "../util/color" 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 @Property
width: number = 0 width: number = 0
@ -29,7 +33,21 @@ export abstract class View implements IWatcher, Modeling {
@Property @Property
alpha?: number 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*/ /** Anchor start*/
get left() { get left() {
return this.x return this.x
@ -62,13 +80,9 @@ export abstract class View implements IWatcher, Modeling {
} }
/** Anchor end*/ /** Anchor end*/
__dirty_props__?: { [index: string]: Model | undefined } __dirty_props__: { [index: string]: Model | undefined } = {}
onPropertyChanged(propKey: string, oldV: Model, newV: Model): void { 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 if (newV instanceof Object
&& Reflect.has(newV, 'toModel') && Reflect.has(newV, 'toModel')
&& Reflect.get(newV, 'toModel') instanceof Function) { && Reflect.get(newV, 'toModel') instanceof Function) {