Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
mricle opened this issue Jan 3, 2017 · 18 comments

Comments

@mricle
Copy link

mricle commented Jan 3, 2017

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

sorrycc commented Jan 3, 2017

先 model 前先 unmodel 下。

@mricle
Copy link
Author

mricle commented Jan 4, 2017

加了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'));
        });
      },
    }
];

@sorrycc
Copy link
Member

sorrycc commented Jan 4, 2017

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

@mricle
Copy link
Author

mricle commented Jan 4, 2017

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

@MelonYii
Copy link

MelonYii commented Jan 4, 2017

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

@sorrycc
Copy link
Member

sorrycc commented Jan 4, 2017

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

@szwork2013
Copy link

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

@szwork2013
Copy link

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

@nianhua110
Copy link

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

@szwork2013
Copy link

szwork2013 commented Jan 10, 2017

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} />
} 

@szwork2013
Copy link

szwork2013 commented Jan 10, 2017

 //在首页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');

@sorrycc
Copy link
Member

sorrycc commented Jan 10, 2017

@szwork2013
Copy link

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

@szwork2013
Copy link

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

@nianhua110
Copy link

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

@ghost
Copy link

ghost commented Jan 18, 2017

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

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

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

@DickyT
Copy link

DickyT commented Jan 21, 2017

不需要unmodel

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

和@xttianma 的异曲同工

@sorrycc
Copy link
Member

sorrycc commented Jan 22, 2017

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

@sorrycc sorrycc closed this as completed Jan 22, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants