889 lines
35 KiB
JavaScript
889 lines
35 KiB
JavaScript
"use strict";
|
||
Object.defineProperty(exports, "__esModule", { value: true });
|
||
exports.createComponent = createComponent;
|
||
/// <reference path="../node_modules/@types/wechat-miniprogram/index.d.ts" />
|
||
const assert_1 = require("oak-domain/lib/utils/assert");
|
||
const types_1 = require("oak-domain/lib/types");
|
||
const page_common_1 = require("./page.common");
|
||
const lodash_1 = require("oak-domain/lib/utils/lodash");
|
||
const OakProperties = {
|
||
oakId: '',
|
||
oakPath: '',
|
||
oakParentEntity: '',
|
||
oakFrom: '',
|
||
oakActions: '',
|
||
oakZombie: false,
|
||
oakDisablePulldownRefresh: false,
|
||
};
|
||
const OakPropertyTypes = {
|
||
oakId: String,
|
||
oakPath: String,
|
||
oakParentEntity: String,
|
||
oakFrom: String,
|
||
oakActions: String,
|
||
oakZombie: Boolean,
|
||
oakDisablePulldownRefresh: Boolean,
|
||
};
|
||
const oakBehavior = Behavior({
|
||
methods: {
|
||
t(key, params) {
|
||
return this.features.locales.t(key, params);
|
||
},
|
||
addFeatureSub(name, callback) {
|
||
const unsubHandler = this.features[name].subscribe(callback);
|
||
this.featuresSubscribed.push({
|
||
name,
|
||
callback,
|
||
unsubHandler,
|
||
});
|
||
},
|
||
removeFeatureSub(name, callback) {
|
||
const f = this.featuresSubscribed.find((ele) => ele.callback === callback && ele.name === name);
|
||
(0, lodash_1.pull)(this.featuresSubscribed, f);
|
||
f.unsubHandler && f.unsubHandler();
|
||
},
|
||
unsubscribeAll() {
|
||
this.featuresSubscribed.forEach((ele) => {
|
||
if (ele.unsubHandler) {
|
||
ele.unsubHandler();
|
||
ele.unsubHandler = undefined;
|
||
}
|
||
});
|
||
},
|
||
subscribeAll() {
|
||
this.featuresSubscribed.forEach((ele) => {
|
||
if (!ele.unsubHandler) {
|
||
ele.unsubHandler = this.features[ele.name].subscribe(ele.callback);
|
||
}
|
||
});
|
||
},
|
||
iAmThePage() {
|
||
const pages = getCurrentPages();
|
||
if (pages[pages.length - 1] === this) {
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
setState(data, callback) {
|
||
this.setData(data, () => {
|
||
this.state = this.data;
|
||
callback && callback.call(this);
|
||
});
|
||
},
|
||
reRender() {
|
||
return page_common_1.reRender.call(this, this.oakOption);
|
||
},
|
||
async onLoad(query) {
|
||
/**
|
||
* 小程序以props传递数据,和以页面间参数传递数据的处理不一样,都在这里处理
|
||
* 目前处理的还不是很完善,在实际处理中再做
|
||
*/
|
||
const { properties } = this.oakOption;
|
||
const dataResolved = {};
|
||
const assignProps = (data, property, type) => {
|
||
if (data.hasOwnProperty(property)) {
|
||
let value = data[property];
|
||
if (typeof data[property] === 'string' &&
|
||
type !== 'string') {
|
||
switch (type) {
|
||
case 'boolean': {
|
||
value = new Boolean(data[property]);
|
||
break;
|
||
}
|
||
case 'number': {
|
||
value = new Number(data[property]);
|
||
break;
|
||
}
|
||
case 'object': {
|
||
value = JSON.parse(data[property]);
|
||
break;
|
||
}
|
||
default: {
|
||
(0, assert_1.assert)(false);
|
||
}
|
||
}
|
||
}
|
||
Object.assign(dataResolved, {
|
||
[property]: value,
|
||
});
|
||
}
|
||
};
|
||
/**
|
||
* query是跳页面时从queryString里传值
|
||
* this.data是properties中有定义的时候在会自动赋值,这里没必要再处理一遍
|
||
*/
|
||
if (properties) {
|
||
for (const key in properties) {
|
||
if (query[key]) {
|
||
assignProps(query, key, typeof properties[key]);
|
||
}
|
||
}
|
||
}
|
||
for (const key in OakProperties) {
|
||
if (query[key]) {
|
||
assignProps(query, key, typeof OakProperties[key]);
|
||
}
|
||
}
|
||
if (Object.keys(dataResolved).length > 0) {
|
||
this.setState(dataResolved);
|
||
}
|
||
},
|
||
save(key, item) {
|
||
return this.features.localStorage.save(key, item);
|
||
},
|
||
load(key) {
|
||
return this.features.localStorage.load(key);
|
||
},
|
||
clear(key) {
|
||
if (key) {
|
||
return this.features.localStorage.remove(key);
|
||
}
|
||
return this.features.localStorage.clear();
|
||
},
|
||
setNotification(data) {
|
||
this.features.notification.setNotification(data);
|
||
},
|
||
consumeNotification() {
|
||
return this.features.notification.consumeNotification();
|
||
},
|
||
setMessage(data) {
|
||
return this.features.message.setMessage(data);
|
||
},
|
||
consumeMessage() {
|
||
return this.features.message.consumeMessage();
|
||
},
|
||
navigateBack(delta) {
|
||
return this.features.navigator.navigateBack(delta);
|
||
},
|
||
navigateTo(option, state) {
|
||
return this.features.navigator.navigateTo(option, state);
|
||
},
|
||
redirectTo(option, state) {
|
||
return this.features.navigator.redirectTo(option, state);
|
||
},
|
||
switchTab(option, state) {
|
||
return this.features.navigator.switchTab(option, state);
|
||
},
|
||
clean(lsn, dontPublish, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.clean(path2, lsn, dontPublish);
|
||
},
|
||
savePoint() {
|
||
return this.features.runningTree.savePoint();
|
||
},
|
||
isDirty(path) {
|
||
return this.features.runningTree.isDirty(path || this.state.oakFullpath);
|
||
},
|
||
execute(action, messageProps, path, opers) {
|
||
return page_common_1.execute.call(this, action, path, messageProps, opers);
|
||
},
|
||
getFreshValue(path) {
|
||
return page_common_1.getFreshValue.call(this, path);
|
||
},
|
||
select(entity, selection) {
|
||
return page_common_1.select.call(this, entity, selection);
|
||
},
|
||
checkOperation(entity, { action, data, filter }, checkerTypes, cacheInsensative) {
|
||
return this.features.cache.checkOperation(entity, {
|
||
action,
|
||
data,
|
||
filter,
|
||
}, checkerTypes, cacheInsensative);
|
||
},
|
||
tryExecute(path, action) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
const operations = this.features.runningTree.getOperations(path2);
|
||
if (operations?.length) {
|
||
for (const oper of operations) {
|
||
const { entity, operation } = oper;
|
||
const operation2 = action ? {
|
||
...operation,
|
||
action,
|
||
} : operation;
|
||
const result = this.checkOperation(entity, operation2);
|
||
if (result !== true) {
|
||
return result;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
getOperations(path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.getOperations(path2);
|
||
},
|
||
async refresh(pageNumber) {
|
||
return page_common_1.refresh.call(this, pageNumber);
|
||
},
|
||
loadMore() {
|
||
return page_common_1.loadMore.call(this);
|
||
},
|
||
getId() {
|
||
return this.features.runningTree.getId(this.state.oakFullpath);
|
||
},
|
||
setNamedFilters(filters, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.setNamedFilters(path2, filters, refresh);
|
||
},
|
||
setFilters(filters, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.setNamedFilters(path2, filters);
|
||
},
|
||
getFilters(path) {
|
||
if (this.state.oakFullpath) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
const namedFilters = this.features.runningTree.getNamedFilters(this.state.oakFullpath);
|
||
return namedFilters.map(({ filter }) => {
|
||
if (typeof filter === 'function') {
|
||
return filter();
|
||
}
|
||
return filter;
|
||
});
|
||
}
|
||
},
|
||
getFilterByName(name, path) {
|
||
if (this.state.oakFullpath) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
const filter = this.features.runningTree.getNamedFilterByName(path2, name);
|
||
if (filter?.filter) {
|
||
if (typeof filter.filter === 'function') {
|
||
return filter.filter();
|
||
}
|
||
return filter.filter;
|
||
}
|
||
}
|
||
},
|
||
addNamedFilter(namedFilter, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.addNamedFilter(path2, namedFilter, refresh);
|
||
},
|
||
removeNamedFilter(namedFilter, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.removeNamedFilter(path2, namedFilter, refresh);
|
||
},
|
||
removeNamedFilterByName(name, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.removeNamedFilterByName(path2, name, refresh);
|
||
},
|
||
setNamedSorters(namedSorters, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.setNamedSorters(path2, namedSorters, refresh);
|
||
},
|
||
getSorters(path) {
|
||
if (this.state.oakFullpath) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
const namedSorters = this.features.runningTree.getNamedSorters(path2);
|
||
const sorters = namedSorters
|
||
.map(({ sorter }) => {
|
||
if (typeof sorter === 'function') {
|
||
return sorter();
|
||
}
|
||
return sorter;
|
||
})
|
||
.filter((ele) => !!ele);
|
||
return sorters;
|
||
}
|
||
},
|
||
getSorterByName(name, path) {
|
||
if (this.state.oakFullpath) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
const sorter = this.features.runningTree.getNamedSorterByName(path2, name);
|
||
if (sorter?.sorter) {
|
||
if (typeof sorter.sorter === 'function') {
|
||
const sortItem = sorter.sorter();
|
||
// 要支持自定义sorter函数返回完整的sorter,但这种sorter应当确保是无名的不被查找
|
||
(0, assert_1.assert)(!(sortItem instanceof Array), '不应该有非item的sorter被查找');
|
||
return sortItem;
|
||
}
|
||
return sorter.sorter;
|
||
}
|
||
}
|
||
},
|
||
addNamedSorter(namedSorter, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.addNamedSorter(path2, namedSorter, refresh);
|
||
},
|
||
removeNamedSorter(namedSorter, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.removeNamedSorter(path2, namedSorter, refresh);
|
||
},
|
||
removeNamedSorterByName(name, refresh, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.removeNamedSorterByName(path2, name, refresh);
|
||
},
|
||
getPagination(path) {
|
||
if (this.state.oakFullpath) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.getPagination(path2);
|
||
}
|
||
},
|
||
setPageSize(pageSize, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.setPageSize(path2, pageSize);
|
||
},
|
||
setCurrentPage(currentPage, path) {
|
||
(0, assert_1.assert)(currentPage !== 0);
|
||
if (this.state.oakEntity && this.state.oakFullpath) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.setCurrentPage(path2, currentPage);
|
||
}
|
||
},
|
||
addItem(data, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.addItem(path2, data);
|
||
},
|
||
addItems(data, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.addItems(path2, data);
|
||
},
|
||
updateItem(data, id, action, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.updateItem(path2, data, id, action);
|
||
},
|
||
updateItems(data, ids, action, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.updateItems(path2, data, ids, action);
|
||
},
|
||
removeItem(id, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.removeItem(path2, id);
|
||
},
|
||
removeItems(ids, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.removeItems(path2, ids);
|
||
},
|
||
recoverItem(id, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.recoverItem(path2, id);
|
||
},
|
||
recoverItems(ids, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.recoverItems(path2, ids);
|
||
},
|
||
resetItem(id, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
this.features.runningTree.resetItem(path2, id);
|
||
},
|
||
setId(id) {
|
||
return this.features.runningTree.setId(this.state.oakFullpath, id);
|
||
},
|
||
unsetId() {
|
||
return this.features.runningTree.unsetId(this.state.oakFullpath);
|
||
},
|
||
update(data, action, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.update(path2, data, action);
|
||
},
|
||
create(data, path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.create(path2, data);
|
||
},
|
||
remove(path) {
|
||
const path2 = path
|
||
? `${this.state.oakFullpath}.${path}`
|
||
: this.state.oakFullpath;
|
||
return this.features.runningTree.remove(path2);
|
||
},
|
||
isCreation(path) {
|
||
// 调用getFreshValue,不redo的情况下如果是creation返回应当是空
|
||
const value = this.getFreshValue(path);
|
||
(0, assert_1.assert)(!(value instanceof Array));
|
||
return value?.$$createAt$$ === 1;
|
||
},
|
||
async aggregate(aggregation) {
|
||
return await this.features.cache.aggregate(this.state.oakEntity, aggregation);
|
||
},
|
||
loadMissedLocales(key) {
|
||
this.features.locales.loadMissedLocale(key);
|
||
},
|
||
subDataEvents(events, callback) {
|
||
return this.features.subscriber.sub(events, callback);
|
||
},
|
||
},
|
||
observers: {
|
||
oakPath(data) {
|
||
if (data && data !== this.prevState.oakFullpath) {
|
||
(0, assert_1.assert)(data);
|
||
if (this.oakLifetime !== 'ready') {
|
||
// 在init状态小程序也会调这个observer,先忽略之
|
||
return;
|
||
}
|
||
const pathState = page_common_1.onPathSet.call(this, this.oakOption, this.iAmThePage());
|
||
this.setState(pathState, async () => {
|
||
if (this.prevState.oakFullpath === undefined) {
|
||
// oakFullpath后置的情况,容一下错
|
||
if (this.oakLifetime !== 'ready') {
|
||
// 在init状态小程序也会调这个observer,先忽略之
|
||
return;
|
||
}
|
||
// 如果每个页面都在oakFullpath形成后再渲染子结点,这个if感觉是不应该命中的
|
||
console.warn('发生了结点先形成再配置oakPath的情况,请检查代码修正');
|
||
this.oakOption.lifetimes?.ready &&
|
||
this.oakOption.lifetimes?.ready.call(this);
|
||
const { oakFullpath } = this.state;
|
||
if (oakFullpath && !this.features.runningTree.isListChildOrStale(oakFullpath)) {
|
||
await this.refresh();
|
||
this.oakOption.lifetimes?.mature && this.oakOption.lifetimes.mature.call(this);
|
||
}
|
||
else {
|
||
this.reRender();
|
||
}
|
||
}
|
||
else {
|
||
// listNode修改子结点上的oakPath时能跑到这里,直接reRender
|
||
this.reRender();
|
||
}
|
||
});
|
||
}
|
||
},
|
||
oakId(data) {
|
||
if (this.oakLifetime !== 'ready') {
|
||
// 在init状态小程序也可能会调这个observer,先忽略之
|
||
return;
|
||
}
|
||
// bugfixed: oakId是props,不能用prevState来追踪其前项值
|
||
if (this.state.oakFullpath) {
|
||
if (data) {
|
||
this.features.runningTree.setId(this.state.oakFullpath, data);
|
||
}
|
||
else {
|
||
this.features.runningTree.unsetId(this.state.oakFullpath);
|
||
}
|
||
}
|
||
},
|
||
},
|
||
});
|
||
function translateListeners(listeners) {
|
||
if (listeners) {
|
||
const result = {};
|
||
for (const ln in listeners) {
|
||
result[ln] = function (...args) {
|
||
// 实测中小程序也是在update之后再调用observer,此时state上的值已经变成后项,因此增加prevState来缓存之
|
||
const propNames = ln.split(',');
|
||
const prev = {};
|
||
const next = {};
|
||
let dirty = false;
|
||
propNames.forEach((pn, idx) => {
|
||
prev[pn] = this.prevState[pn];
|
||
next[pn] = args[idx];
|
||
if (prev[pn] !== next[pn]) {
|
||
dirty = true;
|
||
}
|
||
});
|
||
if (dirty) {
|
||
listeners[ln].call(this, prev, next);
|
||
}
|
||
};
|
||
}
|
||
return result;
|
||
}
|
||
}
|
||
function translatePropertiesToPropertyDefinitions(properties) {
|
||
const definitions = {};
|
||
if (properties) {
|
||
Object.keys(properties).forEach((prop) => {
|
||
if (properties[prop] === null) {
|
||
definitions[prop] = {
|
||
type: null,
|
||
value: null,
|
||
};
|
||
return;
|
||
}
|
||
switch (typeof properties[prop]) {
|
||
case 'string': {
|
||
if (properties[prop]) {
|
||
definitions[prop] = {
|
||
type: String,
|
||
value: properties[prop],
|
||
};
|
||
}
|
||
else {
|
||
definitions[prop] = String;
|
||
}
|
||
break;
|
||
}
|
||
case 'boolean': {
|
||
definitions[prop] = {
|
||
type: Boolean,
|
||
value: properties[prop],
|
||
};
|
||
break;
|
||
}
|
||
case 'number': {
|
||
definitions[prop] = {
|
||
type: Number,
|
||
value: properties[prop],
|
||
};
|
||
break;
|
||
}
|
||
case 'object': {
|
||
if (properties[prop] instanceof Array) {
|
||
if (properties[prop].length > 0) {
|
||
definitions[prop] = {
|
||
type: Array,
|
||
value: properties[prop],
|
||
};
|
||
}
|
||
else {
|
||
definitions[prop] = Array;
|
||
}
|
||
}
|
||
else {
|
||
if (Object.keys(properties[prop]).length > 0) {
|
||
definitions[prop] = {
|
||
type: Object,
|
||
value: properties[prop],
|
||
};
|
||
}
|
||
else {
|
||
definitions[prop] = Object;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
case 'function': {
|
||
Object.assign(definitions, {
|
||
[prop]: Function,
|
||
});
|
||
}
|
||
default: {
|
||
// 小程序也支持传函数 https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html
|
||
// 其它什么类型都写null,小程序能识别出来
|
||
Object.assign(definitions, {
|
||
[prop]: null,
|
||
});
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
}
|
||
return definitions;
|
||
}
|
||
function createComponent(option, features) {
|
||
const { entity, data, properties, methods, wechatMp, lifetimes, listeners, } = option;
|
||
const { attached, show, hide, created, detached, ready, moved, error } = lifetimes || {};
|
||
const { options, externalClasses } = wechatMp || {};
|
||
const { onPullDownRefresh, onReachBottom, ...restMethods } = (methods || {});
|
||
const observers = translateListeners(listeners);
|
||
return Component({
|
||
externalClasses,
|
||
behaviors: [oakBehavior],
|
||
data: typeof data !== 'function'
|
||
? Object.assign({}, data, {
|
||
oakFullpath: '',
|
||
oakLoading: !!option.entity && !!option.projection,
|
||
width: 'xs',
|
||
})
|
||
: {
|
||
oakFullpath: '',
|
||
oakLoading: !!option.entity && !!option.projection,
|
||
width: 'xs',
|
||
},
|
||
properties: Object.assign({}, translatePropertiesToPropertyDefinitions(properties), OakPropertyTypes),
|
||
methods: {
|
||
async onPullDownRefresh() {
|
||
if (!this.state.oakLoading &&
|
||
this.iAmThePage() &&
|
||
!this.props.oakDisablePulldownRefresh &&
|
||
!this.state.oakPullDownRefreshLoading) {
|
||
try {
|
||
this.setState({
|
||
oakPullDownRefreshLoading: true,
|
||
});
|
||
await (onPullDownRefresh
|
||
? onPullDownRefresh.call(this)
|
||
: this.refresh());
|
||
lifetimes?.mature && lifetimes.mature.call(this);
|
||
this.setState({
|
||
oakPullDownRefreshLoading: false,
|
||
});
|
||
await wx.stopPullDownRefresh();
|
||
}
|
||
catch (err) {
|
||
this.setState({
|
||
oakPullDownRefreshLoading: false,
|
||
});
|
||
await wx.stopPullDownRefresh();
|
||
throw err;
|
||
}
|
||
}
|
||
else {
|
||
await wx.stopPullDownRefresh();
|
||
}
|
||
},
|
||
async onReachBottom() {
|
||
if (!this.state.oakLoadingMore &&
|
||
this.iAmThePage() &&
|
||
this.oakOption.isList) {
|
||
await (onReachBottom
|
||
? onReachBottom.call(this)
|
||
: this.loadMore());
|
||
}
|
||
},
|
||
...restMethods,
|
||
},
|
||
observers,
|
||
pageLifetimes: {
|
||
show() {
|
||
const { show } = this.oakOption.lifetimes || {};
|
||
show && show.call(this);
|
||
this.reRender();
|
||
// this.subscribeAll();
|
||
},
|
||
hide() {
|
||
const { hide } = this.oakOption.lifetimes || {};
|
||
hide && hide.call(this);
|
||
/**
|
||
* 不能unsubscribeAll,小程序的页面不会销毁,如果一个页面需要token才能取数据,这时候去了登录页再回来就得依靠feature上的subscribe来refresh
|
||
* by Xc 20250913
|
||
*/
|
||
// this.unsubscribeAll();
|
||
},
|
||
resize(resizeOption) {
|
||
const { resize } = this.oakOption.lifetimes || {};
|
||
resize && resize.call(this, resizeOption);
|
||
}
|
||
},
|
||
lifetimes: {
|
||
created() {
|
||
const { setData } = this;
|
||
this.state = this.data;
|
||
this.props = this.data;
|
||
this.prevState = {};
|
||
this.setData = (data, callback) => {
|
||
this.prevState = (0, lodash_1.cloneDeep)(this.data);
|
||
setData.call(this, data, () => {
|
||
this.state = this.data;
|
||
this.props = this.data;
|
||
callback && callback.call(this);
|
||
});
|
||
};
|
||
this.oakOption = option;
|
||
this.features = features;
|
||
this.featuresSubscribed = [];
|
||
created && created.call(this);
|
||
this._readyCalled = false;
|
||
this.oakLifetime = 'created';
|
||
},
|
||
attached() {
|
||
if (typeof data === 'function') {
|
||
// ts的编译好像有问题,这里不硬写as过不去
|
||
const data2 = data.call(this);
|
||
this.setData(data2, () => {
|
||
const fnData = {};
|
||
for (const k in this.data) {
|
||
if (typeof this.data[k] === 'function') {
|
||
fnData[k] = this.data[k].bind(this);
|
||
}
|
||
}
|
||
if (Object.keys(fnData).length > 0) {
|
||
this.setData(fnData);
|
||
}
|
||
});
|
||
}
|
||
else {
|
||
const fnData = {};
|
||
for (const k in this.data) {
|
||
if (typeof this.data[k] === 'function') {
|
||
fnData[k] = this.data[k].bind(this);
|
||
}
|
||
}
|
||
if (Object.keys(fnData).length > 0) {
|
||
this.setData(fnData);
|
||
}
|
||
}
|
||
this.addFeatureSub('locales', () => this.reRender());
|
||
if (option.entity) {
|
||
this.addFeatureSub('cache', () => this.reRender());
|
||
}
|
||
if (option.features) {
|
||
option.features.forEach((ele) => {
|
||
if (typeof ele === 'string') {
|
||
this.addFeatureSub(ele, () => this.reRender());
|
||
}
|
||
else {
|
||
(0, assert_1.assert)(typeof ele === 'object');
|
||
const { feature, behavior, callback } = ele;
|
||
this.addFeatureSub(feature, async () => {
|
||
if (behavior) {
|
||
switch (behavior) {
|
||
case 'reRender': {
|
||
this.reRender();
|
||
return;
|
||
}
|
||
default: {
|
||
(0, assert_1.assert)(behavior === 'refresh');
|
||
await this.refresh(undefined, true);
|
||
lifetimes?.mature && lifetimes.mature.call(this);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
else if (callback) {
|
||
callback.call(this);
|
||
}
|
||
else {
|
||
this.reRender();
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
attached && attached.call(this);
|
||
if (this.props.oakPath ||
|
||
(this.iAmThePage() && this.oakOption.path)) {
|
||
const pathState = page_common_1.onPathSet.call(this, this.oakOption, this.iAmThePage());
|
||
this.setState(pathState, async () => {
|
||
if (this.oakLifetime === 'detached') {
|
||
return;
|
||
}
|
||
const { oakFullpath } = this.state;
|
||
if (oakFullpath && !this.features.runningTree.isListChildOrStale(oakFullpath)) {
|
||
try {
|
||
await this.refresh();
|
||
lifetimes?.mature && lifetimes.mature.call(this);
|
||
}
|
||
catch (err) {
|
||
if (err instanceof types_1.OakException) {
|
||
err.tag2 = true;
|
||
}
|
||
throw err;
|
||
}
|
||
}
|
||
else {
|
||
this.reRender();
|
||
}
|
||
if (this.oakLifetime === 'detached') {
|
||
return;
|
||
}
|
||
this.oakLifetime = 'attached';
|
||
if (this._readyCalled) {
|
||
// 小程序生命周期里的ready已经调用过了,在这里调用ready
|
||
try {
|
||
ready && await ready.call(this);
|
||
}
|
||
catch (err) {
|
||
if (err instanceof types_1.OakException) {
|
||
err.tag2 = true;
|
||
}
|
||
throw err;
|
||
}
|
||
if (this.oakLifetime === 'detached') {
|
||
return;
|
||
}
|
||
this.oakLifetime = 'ready';
|
||
}
|
||
});
|
||
}
|
||
else if (!this.oakOption.entity) {
|
||
this.reRender();
|
||
this.oakLifetime = 'attached';
|
||
}
|
||
},
|
||
detached() {
|
||
this.unsubscribeAll();
|
||
this.state.oakFullpath && page_common_1.destroyNode.call(this, this.iAmThePage(), this.state.oakFullpath);
|
||
detached && detached.call(this);
|
||
this.oakLifetime = 'detached';
|
||
},
|
||
async ready() {
|
||
/* // 等oakFullpath构建完成后再ready
|
||
// 这代码已经看不懂,感觉没用。 by Xc 20240701
|
||
if (this.state.oakFullpath) {
|
||
if (this.props.oakId) {
|
||
this.features.runningTree.setId(
|
||
this.state.oakFullpath,
|
||
this.props.oakId
|
||
);
|
||
}
|
||
ready && ready.call(this);
|
||
}
|
||
else if (!this.oakOption.entity) {
|
||
ready && ready.call(this);
|
||
this.oakLifetime = 'ready';
|
||
} */
|
||
if (this.oakLifetime === 'attached') {
|
||
try {
|
||
ready && await ready.call(this);
|
||
}
|
||
catch (err) {
|
||
if (err instanceof types_1.OakException) {
|
||
err.tag2 = true;
|
||
}
|
||
throw err;
|
||
}
|
||
this.oakLifetime = 'ready';
|
||
}
|
||
this._readyCalled = true;
|
||
},
|
||
moved() {
|
||
moved && moved.call(this);
|
||
},
|
||
error(err) {
|
||
error && error.call(this, err);
|
||
},
|
||
},
|
||
});
|
||
}
|