UNPKG

mutants-appfx

Version:

appfx module

229 lines (211 loc) 6.17 kB
import React from 'react'; import PropTypes from 'prop-types'; import Alert from 'mutants-microfx/dist/components/Alert'; import appManager from '../AppManager'; import UILoading from '../components/UILoading'; import './style.less'; import { findActions } from '../controllers/eventPath'; import { observer } from 'mutants-microfx'; class TemplateView extends React.Component { static propTypes = { pid: PropTypes.string.isRequired, sysid: PropTypes.string.isRequired, mid: PropTypes.string.isRequired, id: PropTypes.string, view: PropTypes.func.isRequired, viewModel: PropTypes.object.isRequired, app: PropTypes.object.isRequired, handleEvent: PropTypes.func.isRequired, } static childContextTypes = { pid: PropTypes.string, sysid: PropTypes.string, mid: PropTypes.string, id: PropTypes.string, onEvent: PropTypes.func, viewModel: PropTypes.object, appState: PropTypes.object, display: PropTypes.bool, } getChildContext() { return { pid: this.props.pid, sysid: this.props.sysid, mid: this.props.mid, id: this.props.id, viewModel: this.props.viewModel, onEvent: this.props.handleEvent, appState: this.props.app.state, display: this.props.pid === this.props.app.pid, }; } render() { const props = { pid: this.props.pid, sysid: this.props.sysid, mid: this.props.mid, id: this.props.id, viewModel: this.props.viewModel, onEvent: this.props.handleEvent, appState: this.props.app.state, display: this.props.pid === this.props.app.pid, } return <this.props.view {...props}/> } } @observer export default class TemplateProvider extends React.Component { static propTypes = { pid: PropTypes.string, sysid: PropTypes.string, mid: PropTypes.string.isRequired, id: PropTypes.string, } state = { loading: true } async openApp() { if (this.state.sysid === this.sysid && this.state.mid === this.mid && this.state.pid === this.pid) { return; } this.sysid = this.state.sysid; this.mid = this.state.mid; this.pid = this.state.pid; let state; UILoading.show(); try { const app = await appManager.open(this.props) state = { loading: false, app } UILoading.destroy(); } catch (err) { console.error(err); state = { error: err.message, loading: false } UILoading.destroy(); } this.setState(state); } // static getDerivedStateFromProps(nextProps, prevState) { // if (prevState.sysid != nextProps.sysid || // prevState.mid != nextProps.mid || // (prevState.pid != nextProps.pid)) { // return { // sysid: nextProps.sysid, // mid: nextProps.mid, // pid: nextProps.pid, // loading: true, // error: null, // } // } // return null; // } constructor(props) { super(); this.state.sysid = props.sysid; this.state.mid = props.mid; this.state.pid = props.pid; } componentWillReceiveProps(nextProps) { if (this.state.sysid != nextProps.sysid || this.state.mid != nextProps.mid || (this.state.pid != nextProps.pid)) { this.setState({ sysid: nextProps.sysid, mid: nextProps.mid, pid: nextProps.pid, loading: true, error: null, }) } } componentDidMount() { this.openApp().catch(err => console.error(err)); } componentDidUpdate() { this.openApp().catch(err => console.error(err)); } handleEvent = async (viewitem, name, args) => { const app = this.state.app; if (!app) { return; } const eid = await app.pushEvent(name); try { // 执行元数据配置的行为 const action = viewitem && viewitem[name]; if (action) { await app.executeAction(action.name, { ...action.toJS().args, ...args }); } // 支持controller的eventPath const actions = new Set(findActions(app.viewController, name).concat(findActions(app.controller, name))); for (const it of actions) { await app.executeAction(it, { ...args }); } // 触发事件规则 if (viewitem) { await app.triggerEvent(viewitem.name + '.' + name, { ...args }); } await app.popEvent(eid); } catch (err) { await app.popEvent(eid); throw err; } } render() { // 加载中保持界面不变,减少闪烁 const app = this.state.app; if (!app) { if (this.state.error) { return <Alert message={this.state.error}/> } return null; } // const views = appManager.apps.values().reduce((views, app) => views.concat(app.views.slice().map((it, i) => ({ // ...it, // sysid: app.module.sysid, // mid: app.module.mid, // viewModel: app.viewModels[i].viewModel, // state: app.state.toJS(), // app, // }))), []); // return (<div className='app'> // {this.state.error?<Alert message={this.state.error}/>:null} // {views.map((it)=>{ // return <div key={it.iid} id={it.mid+'_'+it.pid+'_'+it.iid} className='view' style={{display:it.iid===app.iid?'block':'none'}}> // <TemplateView {...it.state} mid={it.mid} sysid={it.sysid} pid={it.pid} app={it.app} id={it.app.loadedId} // viewModel={it.viewModel} view={it.view} // handleEvent={this.handleEvent} /> // </div> // })} // </div>) const views = app.views; return (<div className='app'> {this.state.error?<Alert message={this.state.error}/>:null} {views.map((it,i)=>{ return <div key={it.pid+'_'+it.iid} id={it.pid+'_'+it.iid} className='view' style={{display:it.iid===app.iid?'block':'none'}}> <TemplateView {...this.props} pid={it.pid} app={app} viewModel={app.viewModels[i].viewModel} view={it.view} handleEvent={this.handleEvent} /> </div> })} </div>) } }