leeluolee / stateman

A tiny foundation that providing nested state-based routing for complex web application.
https://leeluolee.github.io/stateman
MIT License
388 stars 36 forks source link

多级加载问题 #32

Closed zanderpu closed 8 years ago

zanderpu commented 8 years ago

有三个状态"app",“app.list”,"app.list.info",都采用ajax加载内容进行更新。 1

如上图的前端模式,请求#/app的时候将红色区域的html用ajax请求渲染到1中,请求#/app/list的时候将"app.list.info"用ajax请求渲染到3中。

如果按照顺序先访问#/app,然后访问#/app/list 完全没有问题

如果直接请求#app/list的时候会先请求#/app,然后请求#/app/list,这个时候由于同时执行2个ajax请求,如果第2个ajax先执行完毕就会导致无法渲染到3中,因为这个时候第一个ajax还没有执行完,也就是页面上还没有渲染1中的内容。

这个问题应该怎么处理?

leeluolee commented 8 years ago

可以return 一个Promise 对象用于处理异步逻辑, 或者使用option.async. 具体请参考文档, 其实这小东西代码会多起来主要是对异步的支持, 同步的路由库太多了。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>StateMan API test</title>
  <script src="../../stateman.js"></script>
  <style>
  #app{
    background-color: red;
    padding: 20px;

  }
  #app:after{
   visibility: hidden;
   display: block;
   font-size: 0;
   content: " ";
   clear: both;
   height: 0;
  }
  #side {
    background-color: blue;
    width: 400px ;
    float: left;
    height: 400px;
  }
  #main{
    overflow: hidden;
    background-color: yellow;
  }
  #app-list{
    height: 400px;
  }
  </style>
</head>
<body>

<div id='container'>

</div>

<script>
var $ = function(sl){return document.querySelector(sl)}
var stateman = new StateMan();
stateman.state({

  "app": {
    enter: function(option){
      return new Promise(function(resolve, reject){

        $('#container').innerHTML = "<div id='app'><div id='side'>app加载中.....需4S</div><div id='main'></div></div>"
        setTimeout(function(){
          $('#side').innerHTML = 'app加载成功'
          resolve()
        },3000)
      })
    }
  },
  "app.list": function(option){
    var resolve = option.async();
    $('#main').innerHTML = 'app-list加载中'
    setTimeout(function(){
      $('#main').innerHTML = "<div id='app-list'>app-list 加载成功</div>"
      resolve()
    }, 2000)
  }

}).on("notfound", function(){
  this.go('app.list') // if not found
}).on('begin', function(){ })
.start();

</script>
</body>
</html>```
将stateman的路径替换为你自己的
上面是花了两分钟写的例子, 不要介意代码脏, 里面的option.async返回的函数和Promise的resolve的等价的,目的是方便开发者在不支持Promise的浏览器并且不想引入Polyfill 也能使用异步控制
zanderpu commented 8 years ago

非常感谢,解决了我的问题,谢谢