最近切换到一个新项目,使用的技术栈是Require+Backbone,鉴于对鞋厂webapp框架的了解,发现这个新项目有些缺陷,主要是单纯依赖Backbone造成的,也就是Backbone的好和坏都在其中尽显无遗。
说说自己对Backbone优缺点的看法。
Backbone确实是优秀的单页MVC框架,Events自定义事件机制,为Model/View/Colllection提供基础模块通信,Aync模块封装了CRUD的ajax操作,Router/History为开发者提供了路由机制,从很大程度上解决了开发者自己写路由跳转的逻辑。
当然也存在缺陷,面对大型webapp项目,以page为单位的view数量增多时,一方面路由过于集中,路由逻辑变得复杂,甚至有大量对"职责分离"原则缺乏认识的同学会在router中写入大量的业务逻辑,另一方面缺少对view的统一管理,如view的创建、切换、销毁、跳转回退等。
为了弥补Backbone在webapp中的缺陷,可以为其提供页面生命周期管理和路由管理机制。
先来说webapp生命周期管理。
别被生命周期这种大概念吓住了,生命周期就是页面从创建到销毁的一个抽象过程,如果能抽象的好,可以为页面内部的业务逻辑提供良好的管理。
熟悉android activity的同学可以看到在android framework为activity提供相当完美的生命周期,从onCreate到onShow到onHide到onDestroy,开发者只需要在生命周期回调函数中填写相应的业务代码即可。
(注:可以把android的activity当做一个page)
那么我们学习activity是否可以为page(把一个全屏view当成一个page,view即page)提供这种机制,在page被插入到dom节点(viewport)时提供onCreate回调,在page被显示出来时提供onShow回调,以此类推,page还能提供onHide/onDestroy回调。这样前端写业务的同学是不是能更好的专注业务逻辑,无须考虑页面是如何创建销毁,不会导致框架级代码和业务代码混合在一起。
除了对page提供生命周期,我们还可以学习android framework中activity的管理对整个webapp进行管理。
在android应用启动时,会启动全局application,并为activity准备好运行环境,虽然这在基础的android demo上并未可见,是因为android提供了默认的application。
我们在创建webapp的时候,也能提供一个全局的application,为application也提供生命周期,如onCreate/onDestroy等。如webapp在启动时初始化application,等到依赖的框架资源加载完成时,触发onCreate回调,这时默认的第一个page则可以开始创建并显示。
在application的环境下,我们还能提供对view的管理,建立类似activity task/stack的机制。
在android第一个activity启动时,会建立一个默认的stack,将该activity放入其中,每一个activity在stack中被称为一个task,这样在用户回退时可根据stack中的task来自动选择回退,而不需要指定跳转的目标activity。
有了task/stack管理机制,针对webapp也能提供对view的管理。在创建application的时候提供一个stack,当显示一个view的时候将该view作为一个task压入stack中,在页面返回管理时则变得与android activity一样简单。
除此之外,我们还能挖掘activity的高级特性,如standard,singleTop,singleTask,singleInstance,这样可以为view提供很多丰富的特性。
默认standard即创建一个view,将其压入stack,返回时弹出stack;singleTop方式可指定view显示时在stack顶层不能出现两个同样的view;
singleTask模式则不允许一个stack中出现两个同样的view,比如某些特殊的公共页面可指定这种方式;singleInstance则是单独为该view创建一个stack,这种模式在webapp中暂时少见。
有了以上对view生命周期的管理、application生命周期的管理、application对view stack的管理,我们就能解决Backbone对view管理的不足。
接着说webapp的路由与返回管理。
Backbone提供的路由机制适用于小型的单页应用,如果不对其进行管理则会变得混乱。
我们根据以上application对view的管理,为view封装一个生命周期基类Page,其中包括forward/back等方法,并提供一个对应的PageManager,屏蔽业务开发者对router的直接访问。
根据用户配置的hash:view映射,在用户跳转view的时候直接调用forward指定目标viewname(hash),Page则可调用底层Backbone的router实现url切换,负责view的创建,并且可以通过PageManager将view进行入栈管理,保存view的状态。
而webapp中页面的返回管理,则可以在back中根据PageManager中的stack信息实现页面的默认跳转、指定页面跳转等。
默认跳转则是按照stack出栈顺序返回,指定跳转则可以回到栈中的某一view,并可以指定是将view新建一个置顶到stack top,还是将该view以上的其他view全部销毁。
这只是其中的两个简单返回机制,更多的返回可以通过抽象业务场景来设计。
以上的两点可以解决在构建webapp时遇到的通用问题,不管view/router是否使用Backbone,都能建立一个良好的webapp框架。