SPA的成功离开不这三个东西,分层架构,路由系统,储存系统。分层架构是咱们组织复杂代码的关键,路由系统是将多个页面压缩在一个页面的关键。 其中avalon路由用到了两个单独独立出来的类库 mmRouter 和 mmHistory。javascript
路由其实能够理解成 网站上不一样的网页地址, 若是不是SPA的网站, 浏览器的前进后退,连接到了一个新的页面,整个页面从新刷新; 但若是是SPA网站,由于整个页面是不须要所有刷新的,网站的页面也停留在当前页面,那么怎么解决浏览器的前进后退问题呢, 怎么解决须要定位到特定网页地址的问题呢,因此SPA就引入了路由系统。 下面咱们看看路由是怎么实现的:html
mmRouter和mmHistory地址:https://github.com/RubyLouvre/mmRouter
用requirejs配置mmRouter和mmHistory在网站中的地址java
require.config({//第一块,配置 baseUrl: '', paths: { avalon: ["js/avalon/avalon"],//必须修改源码,禁用自带加载器,或直接删提AMD加载器模块 mmHistory: 'js/avalon/mmHistory', mmRouter: 'js/avalon/mmRouter', } });
'/sub1/index'为路由地址, 当用户在页面点击这个地址的时候,触发callback回调,每一个路由能够单独定义一个callback方法。在这个种子工程中,我都调用了同一个callback方法,就比较适合目录动态生成,须要按需调用不一样的页面的状况。 在这里执行了callback回调以后, console.log(this.path)输出了路径的地址git
//requirejs引用mmRouter require(['mmRouter'],function(mmRouter){ avalon.log("引入avalon"); var model = avalon.define({ $id: "root", name: "tangolivesky" }) //路由的导航回调 function callback() { console.log(this.path); } /*avalon路由方法 '/sub1/index'为路由地址, 当用户在页面点击这个地址的时候,触发callback回调, 每一个路由能够单独定义一个callback方法。在这个种子工程中,我都调用了同一个callback方法,就比较适合 目录动态生成,须要按需调用不一样的页面的状况*/ avalon.router.get("/sub1/index", callback) avalon.router.get("/sub2/index", callback) avalon.history.start({ basepath: "/avalon" }) avalon.scan() });
html页面:
结构比较简单,咱们就定义了两个a 标签,地址前面加上#!, 这个是avalon特有的写法,angularjs是#angularjs
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>avalon工程</title> <script src="js/require/require.js" data-main="main"></script> </head> <body ms-controller="root"> <ul> <li> <a href="#!/sub1/index">导航1</a> </li> <li> <a href="#!/sub2/index">导航2</a> </li> </ul> </body> </html>
当点击导航1,或者导航2,分别在浏览器 控制台中输出了/sub1/index和 /sub2/indexgithub
一个项目都会由好多个子页面和js组成, 就单页面程序来说, 你能够把js进行合并,而后按需加载部分子页面html. 也能够按需加载js和html . 我在这里用的是按需加载js, 再由js中的requirejs text 类库来加载html文件。浏览器
在首页index.html中增长这段代码<div ms-include-src="content"></div>, avalon中ms-include-src是用来加载模板用的架构
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>avalon工程</title> <script src="js/require/require.js" data-main="main"></script> </head> <body ms-controller="root"> <ul> <li> <a href="#!/sub1/index">导航1</a> </li> <li> <a href="#!/sub2/index">导航2</a> </li> </ul> <div ms-include-src="content"></div> </body> </html>
//导航回调 function callback() { var jspath = "modules"; //这里改为您本身的网站地址 ,这个是js路径的变量 var pagepath = ""; //这个是网页的变量 //这段代码的做用是按照路由path 获得须要加载的js路径 var paths = this.path.split("/"); for (var i = 0; i < paths.length; i++) { if (paths[i] != "") { jspath += "/" + paths[i]; pagepath += "_" + paths[i]; } } //console.log(jspath); //console.log(pagepath); require([jspath], function (page) { //这段代码的做用是把pagepath变量 赋给root controller下面的content avalon.vmodels.root.content = pagepath; }); }
同理修改 modules/sub2下面的index.js jsp
sub1下面index.js函数
define(['avalon', 'text!./index.html',], function (avalon,_sub1_index) { avalon.templateCache._sub1_index = _sub1_index })
sub2下面index.js
define(['avalon', 'text!./index.html',], function (avalon,_sub2_index) { avalon.templateCache._sub2_index = _sub2_index })
sub1下面index.html
<div> 第一个页面 </div>
分别点击导航1 和 导航2, 按需加载了sub1的index.js、index.html 和 sub2的index.js、index.html
例子我放在了github中 https://github.com/tangolivesky/avalonSPA_Sample