Skip to content

Commit

Permalink
feat(connector): support the View connect to multiple Services and Co…
Browse files Browse the repository at this point in the history
…ntrollers

re #37
  • Loading branch information
wewoor committed Feb 25, 2021
1 parent d5cacd8 commit ba1037b
Showing 1 changed file with 62 additions and 9 deletions.
71 changes: 62 additions & 9 deletions src/react/connector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@ import Logger from 'mo/common/logger';
import { IComponent } from './component';
import { Controller } from './controller';

export function connect<S, P, C>(
Service: IComponent,
View: React.ComponentType<P>,
Controller: Controller
export type ServiceObject = {
[index: string]: IComponent;
};

export type ControllerObject = {
[index: string]: Controller;
};

export function connect(
Service: IComponent | ServiceObject,
View: React.ComponentType<any>,
Controller?: Controller | ControllerObject,
watchFiled?: object
) {
return class Connector extends React.Component {
state: { lastUpdated: number };
Expand All @@ -19,22 +28,66 @@ export function connect<S, P, C>(
}

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 (
<View
{...this.state}
{...state}
{...this.getServiceState()}
{...this.props}
{...Controller}
/>
Expand Down

0 comments on commit ba1037b

Please sign in to comment.