[关闭]
@njy 2016-01-14T06:07:20.000000Z 字数 4856 阅读 1590

航班管家伙力五星级酒店总结

航班管家 前端

伙力五星级酒店

项目: 伙力五星级酒店

可以在航班管家或者高铁管家APP里底部选项卡(TabBarIOS)第三个旅行服务找到入口: 伙力五星酒店

测试内部地址(http://dev0.xiayizhan.mobi/)
正式服务器地址(http://hotel.huoli.com/)

航班管家NativeAPI(https://www.zybuluo.com/tianfangye/note/105706)

前端是单页面MVVM应用,使用轻量级框架mithril,github文档地址(http://lhorie.github.io/mithril/),用h5页面做的Hybrid App(混合模式移动应用)

详细介绍

  1. 前端代码在工程目录的 v5_src 下。

  2. 使用 FIS(v1.9.14版本,需要运行 node v0.12版本) 作为前端代码管理工具,主要功能包括合并文件、JS 压缩、CSS 压缩、LESS 处理、图片雪碧图自动合并等功能。FIS 使用文档,参考:http://fex-team.github.io/fis-site/docs/beginning/getting-started.html. FIS 配置文件在 v5_src/fis-conf.js.

  3. 前端使用了 Mithril(v) 的前端MVVM 框架,由于 Mithril 并没有提供 JS 的模块工具,自己根据 Mithril 的特点,做了一个 mithril.loader.js ,在 v5_src/scripts/lib/mithril.loader.js 文件。主要功能是加载一个 Mithril 的模块,并且缓存到全局变量中。

  4. 整个 Web App 是单页的,只有部分与主体逻辑关系不大的模块采用了新页面,如地图。

  5. Web App 入口在 v5_src/scripts/run.js,这个文件定义了Mithril 的各个路由对应关系。

  6. Web App 是嵌在航班管家和高铁管家中的,两个管家均采用了 WebViewJSBridge 的方式,为前端提供了一系列的 NativeAPI,赋予了 HTML 一些 Native 的能力。要使用 NativeAPI,首先必须要把 HTML 的域名放在两个管家的白名单中(具体可以咨询 Monkey),其次需要引入 v5_src/lib/native-api.js。NativeAPI 的文档在:https://www.zybuluo.com/tianfangye/note/105706。 文档由公司的包义德维护,他的 QQ 是:516990345。

  7. 前端源码下面放了几个shell 脚本,用来更加快捷的运行 FIS 命令。如,fe.sh、fe_dev0.sh、fe_local.sh、fe_qn.sh等。

选用Mithril:

  1. 轻量级,松耦合,压缩后3kb
  2. API 提供一个模板引擎,带 DOM diff实现,支持路由和组合,路由选择上提供了三种(search,hash,pathname),开始选用search(?),为了兼容微信支付(不能占用?),所以选用了hash(#),格式如(http://dev0.xiayizhan.mobi/#list?checkIn=1445996500336&checkOut=1446082900336&city=%E5%8E%A6%E9%97%A8&keyword=&resetCircles=yes)

    1. m.route.mode = 'hash';
  3. 声明式的绑定,将大量代码逻辑、状态转到ViewModel
  4. 比avalon和angularJS更轻量,与Vue.js相当

在使用中也遇到一些问题:

  1. mithril的事件绑定自动渲染问题autoredraw,它通过绑定 "onhashchange" 或 "onpopstate"事件 来检测变化后redirect(path)来加载js渲染页面, 而onclick后它会自动渲染一次本页面,所以onclick是一个route重定向的命令, 在内存较小的手机,有可能会本页面的render比重定向的render慢,导致本页面不跳转, 目前解决方案自己新添加util.redraw()方法里延时处理
  1. util.redraw = function(){
  2. setTimeout(function(){
  3. m.redraw();
  4. },100);
  5. };

2.auto focus问题, 在做搜索功能时,进入搜索页面,手机键盘自动弹出,异步加载文件或者延时el.focus()后只获取焦点,键盘不弹出,页面是按需加载模块js的,所以导致第一次进入搜索页面键盘不能弹出, 解决方案:把serachApp.js 这个模块合并到indexApp.js这个文件中,不异步加载解决。

  1. m('input.searchApp-input', {
  2. config: function(el, isInit, context) {
  3. if(!isInit){
  4. el.focus();
  5. }
  6. },
  7. type: 'search',
  8. value: ctrl.typingSearchKey(),
  9. oninput: ctrl.searchInputInput.bind(ctrl),
  10. onkeyup: ctrl.searchInputKeyup.bind(ctrl),
  11. placeholder: '搜索位置/酒店名称'
  12. })

3.在定时拉取聊天数据时, 先使用了setInterval, 3s拉取一次, 发现app在实现时,退出打开的聊天webView,回到主页面,聊天webView里的setInterval没有清楚,解决方案,用css3的transition动画代替setInterval

  1. html:
  2. <div id="transitionTimeout"></div>
  3. css:
  4. #transitionTimeout{height: 0; overflow: hidden; opacity: 1; -webkit-transition: 3s ease opacity;}
  5. #transitionTimeout.hide{opacity:0;}
  6. js:
  7. /**
  8. * 每隔 3 秒钟刷新一次消息
  9. */
  10. function initPullTimer(){
  11. $('#transitionTimeout').on('webkitTransitionEnd', function() {
  12. $(this).toggleClass('hide');
  13. pull();
  14. });
  15. $('#transitionTimeout').addClass('hide');
  16. }

4.单页面的拆分:在列表页面做分页后,点击进入详情,然后回退到列表页面,一般浏览器会保留在之前列表页面的位置。但在航班管家的app内发现回直接回退到顶部,无法保留这个位置。解决方案:
单页面的拆分,新建一个createWebView来显示详情,代码结构都不变,只是指定默认的入口文件修改

  1. util.openWindow = function(url, flag) {
  2. if (util.PLATFORM.CURRENT == util.PLATFORM.HBGJ || (flag && util.PLATFORM.CURRENT == util.PLATFORM.GTGJ) ) {
  3. _nativeAPI.invoke('createWebView', {
  4. url: url
  5. });
  6. } else {
  7. window.location.href = url;
  8. }
  9. };
  10. 主页面文件入口:
  11. window.defaultMain = '';
  12. 详情页面文件入口:
  13. window.defaultMain = 'detail/:hotelId/:currentDate/:stayDayCount';

5.http请求文件遭遇拦截问题,在手机移动网络状态下,出现了移动强行插入广告问题。解决方案:改用https的请求文件

6.Promise的使用,越来越多的使用回调了。 mithril使用了大量的闭包,可以使用chrome开发工具Profiles的Collect Javascript CPU Profile 来查看

  1. 核心代码:
  2. var deferred = m.deferred();
  3. return deferred.promise;
  4. 例子:
  5. m.loadRoute = function(route) {
  6. var deferred = m.deferred();
  7. if (__realRoutes[route].ctrl === null) {
  8. loadScript(routesCache[route].path, function() {
  9. realRoutes[route] = window[namespace][routesCache[route].name];
  10. deferred.resolve(window[namespace][routesCache[route].name]);
  11. });
  12. } else {
  13. deferred.resolve(window[namespace][routesCache[route].name]);
  14. }
  15. return deferred.promise;
  16. };
  17. 调用:
  18. m.loadRoute('cityFilter').then(function(cityFilter) {});

Mithril载入页面的3个方法:

默认:m.route(dom, home, realRoutes);
单页面:m.module(document.getElementById('login'), fstar.verifyApp);
m.render(document.getElementById('main2'), myActivity.view(myActivity.controller()));

Worktile

团队协作办公工具选用了Worktile(https://worktile.com/teams/ff731115e7274c7f81de22493a42c690)

sketch

UI交互使用sketch(http://www.sketchcn.com/)来制作

fis v1.9.14

前端自动化工具选用了百度的fis v1.9.14 版本

七牛云存储

服务器储存选用了 七牛云存储(http://www.qiniu.com/),有windows版自动化上传工具

.sh命令行

前端使用debug.sh 和 publish.sh 执行命令行文件 来在测试服务器和七牛上发布文件

nproxy代理

前端使用nproxy(如windows的Fiddler)来调试线上前端代码

studdy 做模拟JSON数据

  1. - request:
  2. method: GET
  3. url: ^/rest/mash?$
  4. response:
  5. headers:
  6. content-type: application/json
  7. file: mash.json
  8. latency : 300
  9. - request:
  10. method: GET
  11. url: ^/rest/messages?$
  12. response:
  13. headers:
  14. content-type: application/json
  15. file: messages.json
  16. latency : 3400
  17. # sudo stubby -d rest/config.yaml
  18. # http://localhost:8882/rest/messages

chrome 开启跨越服务

可以本地起两个服务,tomcat提供接口,fis的node服务器换一个port访问页面实现自动化

  1. njy@localhost:~$cd /Applications/
  2. njy@localhost:/Applications$ls
  3. njy@localhost:/Applications$open Google\ Chrome.app/ --args --disable-web-security
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注