Dva: 1.2.1版本 dynamic-load第二次加载页面时,app.model检查命名会报错

Created on 3 Jan 2017  ·  18Comments  ·  Source: dvajs/dva

 const routes = [
    {
      path: '/',
      name: 'app',
      getComponent(nextState, cb) {
        require.ensure([], require => {
          app.model(require('./models/app'));
          cb(null, require('./routes/App'));
        });
      },
    }
];
discussion question

Most helpful comment

@nianhua110 你get到了没?如果你有过node.js,angular 开发经历的,你会觉得@sorrycc 主持这个react开发架构她的思想很人性化的,大道至简!感谢 @sorrycc 的辛勤付出!谢谢🙏🙏

All 18 comments

先 model 前先 unmodel 下。

加了unmodel,不同路由之间来回切换不报错了,但是同一个路由连续加载就会报错,mapStateToProps中获取不到state中的值了。

function mapStateToProps(state) {
    const { name } = state.app;
    return { name };
}

Uncaught TypeError: Cannot read property 'name' of undefined
    at Connect.mapStateToProps [as finalMapStateToProps]
 const routes = [
    {
      path: '/',
      name: 'app',
      getComponent(nextState, cb) {
        require.ensure([], require => {
          app.unmodel('app');
          app.model(require('./models/app'));
          cb(null, require('./routes/App'));
        });
      },
    }
];

unmodel 后数据就没了,所以在 mapStateToProps 里需要考虑到 state 未定义的情况。

其实这里并不想unmodel,因为dynamic-load的时候多次加载页面,注册model命名校验失败,这种场景下有什么好的解决方案么?

动态加载model时候报app.model: namespace should be unique,切回1.1.0版本就没这个问题了。

@MelonYii 应该是动态加载 model 应该不会有这个问题的,app.model 注册的 model 的 namespace 之前已存在才会报错。相关用例:https://github.com/dvajs/dva/blob/e6030af/test/app.model-test.js#L39-L108

@mricle @sorrycc @MelonYii 现在简单处理我想可以这样:首页一次性加载完model, 在routes里就只动态加载
route页面:
比如:
app.unmodel('app');
app.model(require('./models/app')); 这两行就不要了。

反正一次性加载model后就是一个对象集合,应该不是很影响性能。

@ @szwork2013 如何只动态加载页面?

import React, {PropTypes} from "react";
import {Router, Route,IndexRoute,Redirect} from "dva/router";


 //第一种动态加载方法

const IndexPage = (location, callback) => {
  require.ensure([], require => {callback(null,
    require('./indexPage/indexPage.jsx'))}, 'IndexPage')
}; 
const App = (location, callback) => {
  require.ensure([], require => {callback(null,
    require('./App'))}, 'App')
};
const AddPage = (location, callback) => {
  require.ensure([], require => {callback(null,
    require('./addImages/addImages'))}, 'AddPage')
};
const EditPage = (location, callback) => {
  require.ensure([], require => {callback(null,
    require('./edit/edit'))}, 'EditPage')
};

export default function ({history}) {
    return (
        <Router history={history}> 
            <Route path="/" getComponent={App} >
                <IndexRoute getComponent={IndexPage} /> 
                <Route path="/add" getComponent={AddPage}/>
                <Route path="/edit" getComponent={EditPage}/> 
                <Route path="/*" getComponent={IndexPage}/>
            </Route>
        </Router>
    );
};

// 第二种动态加载方法
 export default function ({history}) {
  const routes = [
    {
      path: '/',
      component:require('./app'),
      getIndexRoute (nextState, cb) {
        require.ensure([], require => { 
          cb(null, {component: require('./indexPage/indexPage.jsx')})
        })
      },
      childRoutes: [
        {
          path: 'add',
          name: 'add',
          getComponent (nextState, cb) {
            require.ensure([], require => { 
              cb(null, require('./addImages/addImages'))
            })
          }
        }, {
          path: 'edit',
          name: 'edit',
          getComponent (nextState, cb) {
            require.ensure([], require => { 
              cb(null, require('./edit/edit'))
            })
          }
        } 
      ]
    }
  ]

  return <Router history={history} routes={routes} />
} 
 //在首页index.js文件:
import './index.html';
import './index.less';
import dva from 'dva';
//import { useRouterHistory,browserHistory } from 'dva/router' 

import { useRouterHistory } from 'dva/router';
import { createHistory } from 'history'; 

// 1. Initialize
const app = dva({
  history: useRouterHistory(createHistory)({basename:'/'}),
});

// 2. Plugins
//app.use({});

// 3. Model 一次性加载完model
app.model(require('./models/my')); 
app.model(require('./models/image'));
app.model(require('./models/add'));
app.model(require('./models/edit')); 

// 4. Router 按需加载router
app.router(require('./routes/router.js'));

// 5. Start
app.start('#root');

@nianhua110 你get到了没?如果你有过node.js,angular 开发经历的,你会觉得@sorrycc 主持这个react开发架构她的思想很人性化的,大道至简!感谢 @sorrycc 的辛勤付出!谢谢🙏🙏

@sorrycc对不起,刚才活干的太糙了。

@szwork2013 ,谢谢辣,我先试试。

此类问题的解决办法:
(我在一个个回帖,碰到这个问题那么多人?)

if(!app._models.some(val=>(val.namespace ===  'home')) {
        app.model(require('./models/home'))
}

# 建议开发者: 错误信息能否明确指出XXX, 重复加载,错误文件和行号?

不需要unmodel

try {
  app.model(require(`./models/${model}`));
}
catch(e) {}

和@xttianma 的异曲同工

对动态加载的问题总结了下,有问题在 #533 里跟进。

Was this page helpful?
0 / 5 - 0 ratings

Related issues

seamys picture seamys  ·  4Comments

kpaxqin picture kpaxqin  ·  3Comments

itiwll picture itiwll  ·  4Comments

huyawei picture huyawei  ·  3Comments

mclouvem picture mclouvem  ·  4Comments