AaronFlower / spa-ch

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Single Page Application

定义

SPA, 单页应用是指在浏览器中运行的应用,在使用期间页面不会重新加载。本项目是一个从前端到后端都是用JS语言来实现的应用,即纯'js'栈。

V1.0

Chapter 01 在一个页面上完成的一个demo.

V3.0

Chapter 03 渲染功能容器与管理应用状态。 ####深入理解Shell Shell 是单页应用的主控制器( master controller ), 在我们的架构中是必需的。可以看作是与MVC中Master Controller是一致的,因为它是协调所有从属功能模块的控制器。 Shell 负责以下事情。

  1. 渲染和管理功能容器。
  2. 管理应用状态。
  3. 协调功能模块。 ####创建文件和名字空间 我们会为js/css创建平行的文件结构,这种约定能加快开发,提升质量和简化维护。我们已经选择spa作为单页应用的根名字空间,JS和CSS文件名,JS名字空间和CSS选择器名称都同步使用。这样就可以很容易的追踪那个JS文件搭配那个CSS文件了。 ###管理功能容器 Shell渲染并管理着功能容器。

编写展开和收起聊天滑块方法

我们对聊天滑块函数的要求是适度的。我们需要它具有产品级的质量,但不用过度设计。 下面是我们想要完成的需求。

  1. 开发人员能配置滑块的运动的速度和高度。
  2. 创建单个方法来展开或者收起聊天滑块。
  3. 避免出现竞争条件(race condition ) 即,滑块可能同时在展开和收起。
  4. 开发人员能够传入一个可选的回调函数,会在滑块运动结束时调用。
  5. 创建测试代码,以便确保滑块功能正常。

当发生历史事件时,更改锚

锚组件的一个特殊功能是,在它改变的时候,浏览器不会重新加载页面,但是,锚的改变却会影响浏览器的前进/后退事件。锚组件是只给客户端使用的控件,它是保存应用状态的理想地方。很多单页应用都使用这个技巧。 我们把想保存在浏览器历史当中的应用状态( 本应用的状态就是 extend/retract 啦 )称之为历史事件( history events ),即我们认为 开始或结束聊天是历史事件, 我们通过在单击时改变锚来记住这个历史状态。

关于感叹号 http://localhost/spa.html#!chat=closed, 中哈希符号后的感叹号(#!),用于告诉Google和其它搜索引擎,这个URI可以被搜索索引。

使用锚来驱动应用状态

我们希望始终让锚组件来驱动可书签化的应用状态,这能确保历史功能一直按预期工作。下面的伪代码概括了我们是如何来处理历史事件的。

  1. 当发生历史事件(应用状态改变)时,更改URI的 anchor component( 锚组件 ),以便体现更改的状态。
    • 接收事件的处理程序(onClickChat)调用Shell的工具方法(uriAnchor)来改变锚。
    • 然后事件处理程序退出。
  2. Shell的hashchange事件处理程序注意到了URI变化并按它行事。
    • 将当前状态和新的锚表示的状态做比较
    • 根据比较确定的结果,尝试更改需要修改的应用部分。
    • 如果不能处理请求的变化,则保持当前状态,并恢复锚,以便和状态匹配。

###V4.0 将chat功能模块完全从shell模块分离出来实现。 主要应用的开发模式是:FMVC( Fractal MVC)。设计的架构是,

  1. Shell 可以调用单页应用中的任何子模块。
  2. 功能模块只调用共享的公用模块。
  3. 功能模块之间的相互调用是不允许的。
  4. 功能模块的唯一数据源或者功能只能来自Shell,在配置和初始化期间以参数的形式会给模块的公开方法。

设计方法API

我们希望一直由URI 锚来驱动页面状态,而不是倒过来。

  1. Chat配置API spa.chat.configModule();
  2. Chat初始化API spa.chat.initModule();
  3. Chat的setSliderPosition API sap.chat.setSliderPosition();

###V5.0 Chapter05 将设计和构建Model的people对象。 Model向Shell和功能模块提供业务逻辑和数据。Model不依赖于用户界面(UI),它被分离出来负责逻辑和数据管理。 Model自身通过使用Data模块,从Web服务分离出来。

Model做什么

Model是Shell和所有功能模块访问单页应用的数据和业务逻辑的地方。如果需要登入,我们就调用Model提供的方法。如果想获取人员列表,就从Model获取。如果想获取头信息.....,好了,你懂得!任何希望在功能模块之间共享的或者对应用极为重要的数据和业务,都应该放在Model里面。

Model不做什么

*Model不需要浏览器。*这就意味着Model不可以假定存在document对象,或者存在像document.location这种浏览器特有的方法。让Shell和功能模块来表示Model的数据是『干净的』MVC。 这样分离使得自动化测试和回归测试变得简单。

About


Languages

Language:JavaScript 93.3%Language:HTML 3.4%Language:CSS 3.2%