-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcreate-page.js
155 lines (137 loc) · 3.87 KB
/
create-page.js
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/**
* @copyright Maichong Software Ltd. 2016 http://maichong.it
* @date 2016-10-11
* @author Liang <[email protected]>
*/
'use strict';
import setValue from 'lodash/set';
import getValue from 'lodash/get';
import * as utils from './utils';
/**
* 构建列表数据项
* @param list 原始列表
* @param item 新列表
* @returns {{_: *}}
*/
function buildListItem(list, item) {
if (list && list.length && item.__k !== undefined) {
for (let t of list) {
if (t.__k !== undefined && t.__k === item.__k) {
return Object.assign({}, t, item);
}
}
}
return item;
}
module.exports = function createPage(ComponentClass) {
let config = {};
let page;
config.data = {};
config.name = '';
config._dispatch = function(event) {
let com = this.root;
let target = event.currentTarget || event.target;
let path = target.dataset.path || '';
// $Flow
let handler =
target.dataset['bind' + event.type] ||
target.dataset['catch' + event.type] ||
target.dataset[event.type];
while (path) {
let index = path.indexOf('.');
let key = '';
if (index === -1) {
key = path;
path = '';
} else {
key = path.substr(0, index);
path = path.substr(index + 1);
}
com = com._children[key];
if (!com) {
console.error(
'Can not resolve component by path ' + target.dataset.path
);
return undefined;
}
}
// $Flow 我们知道com在这里一定是一个组件,而非组件数组,但是Flow不知道
if (com[handler]) {
if (__DEV__) {
// $Flow
console.log('%c%s %s(%o)', 'color:#2abb40', com.id, handler, event);
}
return com[handler](event);
}
// $Flow 我们知道com在这里一定是一个组件,而非组件数组,但是Flow不知道
console.error('Can not resolve event handle ' + com.id + '#' + handler);
return undefined;
};
[
'onRouteEnd',
'onUnload',
'onPullDownRefresh',
'onReachBottom'
].forEach(function(name) {
config[name] = function(...args) {
utils.callLifecycle(this.root, name, args);
};
});
config.onLoad = function(options) {
page = this;
page.page = page;
page._show = false;
page._ready = false;
page._loadOptions = options;
page.updateData = function(newData) {
let data = page.data;
Object.keys(newData).forEach(path => {
let dataMap = newData[path];
if (Array.isArray(dataMap)) {
// 如果是组件列表,需要与之前列表数据合并,这样主要为了在子组件嵌套情况下,不丢失底层子组件数据
let list = getValue(data, path); //原有data中列表数据
let newList = dataMap.map(item => buildListItem(list, item));
setValue(data, path, newList);
} else {
setValue(data, path.split('.'), dataMap);
}
});
page.setData(data);
};
let root = (page.root = new ComponentClass({}));
root._config = {};
root.page = page;
root.id = page.__route__;
root.page = page;
try {
root._init('');
} catch (error) {
console.error(error.stack);
}
if (root.onLoad) {
root.onLoad(options);
}
};
config.onReady = function() {
page._ready = true;
utils.callLifecycle(this.root, 'onReady');
};
config.onShow = function() {
page._show = true;
utils.callLifecycle(this.root, 'onShow');
};
config.onHide = function() {
page._show = false;
utils.callLifecycle(this.root, 'onHide');
};
if (ComponentClass.prototype.onShareAppMessage) {
config.onShareAppMessage = function() {
let share = this.root.onShareAppMessage();
if (__DEV__ && !share) {
console.error(this.root.id + ' onShareAppMessage() 没有返回分享数据');
}
return share;
};
}
return config;
};