ecomfe/er

router增加对history的支持

Opened this issue · 14 comments

  1. 跟进技术发展
  2. 可以对传统的 web site 增强,可以对移动平台增强
  3. 内部平台可以使用
  4. url 的架构会更加优雅

曾经试过,OP和RD比较难搞,因为要把大量路径映射到一个页面上……

另外这事应该由locator来做,只要:

  1. 做一个HistoryLocator
  2. 根据当前是否支持History,er/router.setLocator(xxx) er/controller.setLocator(xxx)就好了

这事可以先内部自己做着

Gray Zhang
已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

在 2014年8月6日 星期三,下午10:17,Exodia 写道:

跟进技术发展
可以对传统的 web site 增强,可以对移动平台增强
内部平台可以使用
url 的架构会更加优雅


Reply to this email directly or view it on GitHub (#139).

嗯,搞混了,是应该 locator 走

我算在ER4的规划里面,但3不考虑这个

Gray Zhang
已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

在 2014年8月6日 星期三,下午10:24,Exodia 写道:

嗯,搞混了,是应该 locator 走


Reply to this email directly or view it on GitHub (#139 (comment)).

locator单独拎出来做一个 dep 包如何,这样无所谓er版本问题

我怕太细,ER原本的定位就是“可大可小”,locator单独拆出去在现在我们的环境下没有使用场景……promise和model拆出去是为了支持下一代esui的异步编程及双向绑定

往ER3里加一个history功能的locator也是可以的,但我不建议内部处理掉浏览器兼容性,交给产品线自己去判断和组装即可

另外我打算下一版本把router去掉

Gray Zhang
已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

在 2014年8月6日 星期三,下午10:26,Exodia 写道:

locator单独拎出来做一个 dep 包如何,这样无所谓er版本问题


Reply to this email directly or view it on GitHub (#139 (comment)).

我也支持内部不处理兼容性,提供类似 locator.config({ useHisttory: true })的配置

我觉得应该是一个HashLocator,一个HistoryLocator,默认直接用HashLocator就是完全没有History功能,要高级的怎么用是产品线自己的事

var locator = require(‘er/locator’);
if (History.pushState) {
  var locator = new HistoryLocator();
  require(‘er/router’).setLocator(locator);
  require(‘er/controller’).setLocator(locator);
}

// 不能再用er.start了
require(‘er/controller’).start();
require(‘er/router’).start();
locator.start();

代码会很奇怪是因为er本来是单例的后来才搞成多例,也可以Controller和Router都new一个这样很顺眼了

我觉得一个项目应该很少会出两套 url 的架构方案,基本上不会出现条件语句来创建不同的 locator,而是根据项目需要支持的浏览器去选择一套方案(hash/history)

确实不会,所以我希望让产品线自己去选择其中1个就好

这个检测很简单,是人都会,但只用hash的时候完全没必要把history引进来,所以可以

require([supportHistory ? ‘er/HisotryLocator’ : ‘HashLocator’, ‘er/router’, ‘er/controller’, ‘common/main’], function (Locator, router, controller, main) {
var locator = new Locator();
router.setLocator(locator);
controller.setLocator(locator);

controller.start();
router.start();
locator.start();
main.start();
});

这样不需要History就完全不会把History相关的代码弄进来了

而且,hash和history完全是2套逻辑,也基本没有可复用的代码,放一起和拆成合起来大小没啥区别,能继承去做的事,再配合ioc更容易搞定都不需要上面这样的代码,我们为啥就一定要合成一个来分支实现呢

Gray Zhang
已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

已使用 Sparrow (http://www.sparrowmailapp.com/?sig)

在 2014年8月6日 星期三,下午11:03,Exodia 写道:

我觉得一个项目应该很少会出两套 url 的架构方案,基本上不会出现条件语句来创建不同的 locator,而是根据项目需要支持的浏览器去选择一套方案(hash/history)


Reply to this email directly or view it on GitHub (#139 (comment)).

确实分开实现即可

@Exodiacheckout一下4.0/feature/mvc分支,通过README.md中的方法生成文档,看一下Locator类的接口是否足够满足开发History API为基础的子类。通过源码的注释也可以比较清晰地看出流程

在研究之后其实我有些反对添加History API功能,因为History API有一个巨大的缺点,用户点击链接会导致整个页面的跳转而不是触发个简单的popstate事件,除非对全页所有链接注册click事件(当然用事件冒泡了)并转到history.pushState方法上去

如果要做,这个注册click事件还不能Controller负责,需要Locator这个层级来做,因为像我们系统中的导航他不属于Action,不在Controller管理之下,于是又会形成一个难题,Controller通过注册点击事件来解决子Action跳转的问题,但Locator又要一个事件自己来处理跳转,这里会冲突,且在设计上如果要取消这个冲突就使设计非常丑陋

所以我现在的结论是:

History API有助于多页式项目的局部刷新来增强用户体验,但不适用于单页式项目的开发

所以我现在懂了为啥这么多单页的产品,无论他们技术多牛,像Facebook、Twitter之类,依旧用的是hash

另外现在有2种方案:

  1. Locator是个抽象基类,有2个子类HashLocatorHistoryLocator
  2. Locator默认实现HashLocator的功能,HistoryLocator重写掉需要的方法就行

我比较倾向于第2种, @Exodia 你怎么看

Locator默认实现HashLocator的功能,HistoryLocator重写掉需要的方法就行

支持这个