-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproxy.js
More file actions
127 lines (117 loc) · 3.71 KB
/
proxy.js
File metadata and controls
127 lines (117 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
(function(global, factory){
typeof exports === 'object' && typeof module !== 'undefined' ? eachMethod(module.exports, factory()) :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, eachMethod(global, factory()));
function eachMethod(item,data) {
for(var key in data) {
item[key] = data[key]
}
}
}(this, function() {
function FormatPath(array) {
let str = '';
array.forEach(v => {
if(isNaN(v)) {
str += '.'+v;
} else {
str += `[${v}]`
}
})
return str.substr(1)
}
function createData(value) {
return value instanceof Array ? [...value] : { ...value };
}
function WatchEvent(parentWatchEvent) {
this.eventList = [];
this.parentEvent = [];
if(parentWatchEvent) {
this.parentEvent = [...parentWatchEvent.parentEvent, parentWatchEvent]
}
}
WatchEvent.prototype.find = function() {
let event = [...this.eventList];
this.parentEvent.forEach(v => {
event = event.concat(v.eventList)
})
return event;
}
WatchEvent.prototype.add = function(callback) {
this.eventList.push(callback)
}
WatchEvent.prototype.run = function() {
return this.find()
}
function DataProxy(data, cb, path = [], parentWatchEvent) {
const current = createData(data);
let currentWatch = {};
const watchEvent = new WatchEvent(parentWatchEvent);
for(let key in current) {
if(typeof(current[key]) == 'object') {
current[key] = DataProxy(createData(current[key]), cb, [...path, key], watchEvent)
}
}
const proxy = new Proxy(current, {
get(target, key) {
const currentPath = [...path, key]
return target[key]
},
set(target, key, value, receiver) {
if(key == '__watch') {
currentWatch[value[0]] = value[1];
return true;
}
if(key == '__watch_deep') {
watchEvent.add((data) => setTimeout(() => value({...data, path: path, data: target})))
return true;
}
const currentPath = [...path, key];
if(typeof(value) == 'object') {
value = DataProxy( createData(value), cb, currentPath, watchEvent )
}
if (!(Array.isArray(target) && key === 'length')) {
const data = {
type: 'set',
key,
data: value,
parent: target,
path: currentPath
}
currentWatch[key] && currentWatch[key](data);
target[key] = value;
watchEvent.run().forEach(v => v(data));
cb && cb(data)
}
return Reflect.set(target, key, value, receiver);
},
deleteProperty(target, key) {
const currentPath = [...path, key];
const data = {
type: 'delete',
key,
data: target[key],
parent: target,
path: currentPath
}
if(target instanceof Array) {
target.splice(key, 1)
} else {
delete target[key]
}
currentWatch[key] && currentWatch[key](data);
watchEvent.run().forEach(v => v(data));
cb && cb(data)
return Reflect.deleteProperty(target, key);
}
})
return proxy
}
function watch(target, key, callback) {
if(typeof(key) == 'function') {
target.__watch_deep = key;
} else {
target.__watch = [key, callback]
}
}
return { watch, FormatPath, DataProxy }
}))