From ba1037b7e2916f28764ce1119f2ef8a5b52368fb Mon Sep 17 00:00:00 2001 From: xiaowei Date: Thu, 25 Feb 2021 11:02:48 +0800 Subject: [PATCH] feat(connector): support the View connect to multiple Services and Controllers re #37 --- src/react/connector.tsx | 71 +++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/src/react/connector.tsx b/src/react/connector.tsx index 62d359307..2c4aec7d0 100644 --- a/src/react/connector.tsx +++ b/src/react/connector.tsx @@ -3,10 +3,19 @@ import Logger from 'mo/common/logger'; import { IComponent } from './component'; import { Controller } from './controller'; -export function connect( - Service: IComponent, - View: React.ComponentType

, - Controller: Controller +export type ServiceObject = { + [index: string]: IComponent; +}; + +export type ControllerObject = { + [index: string]: Controller; +}; + +export function connect( + Service: IComponent | ServiceObject, + View: React.ComponentType, + Controller?: Controller | ControllerObject, + watchFiled?: object ) { return class Connector extends React.Component { state: { lastUpdated: number }; @@ -19,22 +28,66 @@ export function connect( } componentDidMount() { - Service.onUpdateState(this.onChange); + if (Service.onUpdateState) { + const service = Service as IComponent; + service.onUpdateState(this.onChange); + } else { + for (const name in Service) { + if (name) { + const service: IComponent = Service[name]; + if (service.onUpdateState) { + service.onUpdateState(this.onChange); + } + } + } + } } - onChange(nextState: S) { - Logger.info(nextState, Service.getState()); + onChange(prevState, nextState) { + Logger.info(prevState, nextState); + if (!watchFiled) { + this.update(); + } else { + // TODO, 目前会全量触发更新,后期根据 watchField 字段来控制更新粒度 + // const prev = get(prevState, watchFiled); + // const next = get(nextState, watchFiled); + // if (!equals(prev, next)) { + // this.update(); + // } + } + } + + update = () => { this.setState({ lastUpdated: Date.now(), }); + }; + + getServiceState() { + const target = {}; + if (Service.onUpdateState) { + const service = Service as IComponent; + Object.assign(target, { ...service.getState() }); + } else { + for (const name in Service) { + if (name) { + const service: IComponent = Service[name]; + if (service.getState) { + Object.assign(target, { + [name]: { ...service.getState() }, + }); + } + } + } + } + return target; } render() { - const state = Service.getState(); return (