如何创建html5上传组件与原生UI组件混合的移动应用程序

Trigger.io:创建 HTML5 与原生 UI 组件混合的移动应用 - 推酷
Trigger.io:创建 HTML5 与原生 UI 组件混合的移动应用
本文将介绍如何使用Trigger.io创建原生的顶部栏、标签栏、以及HTML/CSS/JavaScript的混合型移动应用程序。
以后我们将添加更多的原生UI组件到Trigger.io,但现在你只需要使用web技术就可以在IOS和Android上创建漂亮而流畅的移动应用。
这是一个简单的菜谱应用程序的屏幕截图,我们使用Trigger.io提供的原生UI组件,我们将向你展示该应用程序是如何构建的:
配置Trigger.io,并添加顶部栏和标签栏到应用程序中
给原生控件添加样式
用JavaScript给控件添加监听器
你可以从github中获取项目的源代码:
第一步:创建App并添加顶部栏
你需要使用Trigger.io生成App的基本框架,然后使用web技术来获取原生的UI组件。因此,在开始之前,你需要先进行
,一旦你完成设置只需要运行:
forge create
这时会提示你给app命名,命令完成后会自动生成app的项目文件夹。
让我们开始给app添加一个顶部栏,之后在Android模拟器上运行测试。
将src/config.json文件的代码替换成以下代码:
&author&: &amir@trigger.io&,
&config_version&: &2&,
&description&: &View ingredients for your favorite recipes&,
&modules&: {
&is&: true,
&logging&: {
&level&: &INFO&
&prefs&: true,
&request&: {
&permissions&: []
&tools&: true,
&topbar&: true
&name&: &Recipe list&,
&platform_version&: &v1.3&,
&version&: &0.1&
在模块配置中设置顶部栏可用:“topbar”: true。
然后修改一下index.html
&!DOCTYPE html&
&div class=&content&&
Hello world!
现在你可以使用forge命令运行并测试app了:
forge build
forge run android --android.sdk ~/Desktop/android-sdk-macosx
配置标签栏
在app的底部添加标签栏也很容易,你只需要在src/config.json(模块配置)中加上“tabbar”: true,如下:
&author&: &amir@trigger.io&,
&config_version&: &2&,
&description&: &View ingredients for your favorite recipes&,
&modules&: {
&is&: true,
&logging&: {
&level&: &INFO&
&prefs&: true,
&request&: {
&permissions&: []
&tools&: true,
&topbar&: true,
&tabbar&: true
&name&: &Recipe list&,
&platform_version&: &v1.3&,
&version&: &0.1&
但是,在运行之前,我们还需要添加一些按钮和侦听器。这样,当点击每个选项卡时,我们就可以执行JavaScript来处理页面的切换。
让我们添加一个JavaScript文件,命名为src/js/main.js:
// A helper function so that when we change tab the web view scrolls to the top of the new page
var scrollTop = function () {
setTimeout(function () {
document.body.scrollTop = 0;
// This is the method we are going to call when a tab button is pressed
var updateRecipes = function (search) {
scrollTop();
// For now just pop up a message with the tab which was pressed
alert(search);
// Set a better title for the topbar
forge.topbar.setTitle(&Recipe shopping list&);
// Add our 3 tab buttons to the tabbar and add press listeners
var starterButton = forge.tabbar.addButton({
text: &Starters&,
icon: &img/tomato.png&,
}, function (button) {
button.onPressed.addListener(function () {
updateRecipes(&starter&);
// This is the default button, activate it immediately
button.setActive();
updateRecipes(&starter&);
var mainButton = forge.tabbar.addButton({
text: &Mains&,
icon: &img/pizza.png&,
}, function (button) {
button.onPressed.addListener(function () {
updateRecipes(&main&);
var dessertButton = forge.tabbar.addButton({
text: &Desserts&,
icon: &img/strawberry.png&,
}, function (button) {
button.onPressed.addListener(function () {
updateRecipes(&dessert&);
这里我们调用了forge.topbbar.setTitle,该API会改变顶部的标题,然后用forge.tabbar.addButton来添加标签栏的按钮,以及该按钮的监听器。
我们修改src/index.html这个文件:
&!DOCTYPE html&
&script src=&js/main.js&&&/script&
&div class=&content&&
Hello world!
src/js/main.js文件里面引用了一些图片,这些图片你可以从
中获取,并放在src/img目录里。
这次我们在IOS里面运行测试:
第三步:创建列表视图
OK,现在我们需要创建菜谱列表,并让它们点击后可跳转。
我们将使用轻量级的zepto.js库,以帮助我们处理DOM操作。我们已经发表了一篇关于
的博客。因此,我们就不在这对做介绍了。接下来在菜谱列表中使用HTML/CSS/JavaScript。
首先,让我们将菜谱数据导入到zepto.js库。你可以下载zepto.js和data.js从
,并把它们放在你的src/js目录里。
然后我们更新src/js/的main.js中的updateRecipe功能 - 这是当标签栏按钮被按下时调用的:
var updateRecipes = function (search) {
scrollTop();
$('.content').html('&ul class=&list&&&/ul&');
$.each(data[search], function (i, recipe) {
var el = $('&li&&img src=&'+recipe.thumb+'&&'+recipe.title+'&/li&');
el.on('click', function () {
scrollTop();
$('.content').html('&div class=&recipe&&&h3&'+recipe.title+'&/h3&&img src=&'+recipe.img+'&&&ul class=&ingredients&&&/ul&&p&&a href=&#& onclick=&forge.tabs.open(\''+recipe.source+'\')&&View full recipe&/a&&/p&&/div&');
$.each(recipe.ingredients, function (i, ingredient) {
$('.ingredients').append('&li&'+ingredient+'&/li&');
forge.tabbar.setInactive();
$('.list').append(el);
现在完成应用程序,我们只需要在src/index.html添加一些简单的样式并导入JavaScript文件:
&!DOCTYPE html&
body, html, li, ul {
padding: 0;
margin: 0;
font-size: 1.2
text-align:
.recipe img {
max-width: 80%;
.recipe li {
font-size: 0.9
padding: 2
margin: 0;
padding: 0;
.list li {
border-bottom: 1px solid #
padding: 0;
margin: 0;
width: 100%;
white-space:
text-overflow:
.list li img {
height: 50
padding: 2px 7px 2px 2
vertical-align: middle
&script src=&js/zepto.js&&&/script&
&script src=&js/data.js&&&/script&
&script src=&js/main.js&&&/script&
&div class=&content&&
现在,你运行应用程序就会看起来跟本篇文章的顶部截图一样了。除此之外,你也可以尝试调用以下API来探索顶部栏和标签栏的不同造型:
因此,你也可以使用Trigger.io中的原生UI组件创建出丰富的混合应用程序!
如果你遇到什么问题,你可以查看
,也可以在
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见HTML5框架Agile的使用-移动应用平台ExMobi
<meta name="author" content="黄楠 "/>
第15课&&HTML5框架Agile的使用
HTML5框架Agile的使用视频
HTML5框架Agile的使用
HTML 5是近十年来Web开发标准最巨大的飞跃。和以前的版本不同,HTML 5并非仅仅用来表示Web内容,它的新使命是将Web带入一个成熟的应用平台,在HTML 5平台上,视频,音频,图象,动画,以及同设备的交互都被标准化。
几乎所有人都热衷于开发独立的移动应用,但是HTML5很可能会是独立移动应用的终结者。由于HTML5将应用的功能直接加入其内核,这很可能引导移动技术潮流重新回到浏览器时代。HTML5允许开发者在(移动)浏览器内开发应用,所以如果你正在制定一项桌面或者移动应用的长期发展策略,你可能需要考虑这一点。
下面我们一起来了解HTML5的特性。
HTML5赋予网页更好的意义和结构。借助 header, footer, section, article 这些标签,我们可以实现更具结构化,语义化的 Web 文档。这样,搜索引擎可以更容易索引 Web 站点,我们也可以搜索到更快,更准确的信息。
本地存储特性
基于HTML5开发的网页APP拥有更短的启动时间,更快的联网速度,这些全得益于HTML5 APP Cache,以及本地存储功能。即使在 Internet 连接中断之后也能继续访问HTML5应用。
设备兼容特性
从Geolocation功能的API文档公开以来,HTML5为网页应用开发者们提供了更多功能上的优化选择,带来了更多体验功能的优势。HTML5提供了前所未有的数据与应用接入开放接口。使外部应用可以直接与浏览器内部的数据直接相连,例如视频影音可直接与microphones及摄像头相联。
更有效的连接工作效率,使得基于页面的实时聊天,更快速的网页游戏体验,更优化的在线交流得到了实现。HTML5拥有更有效的服务器推送技术,Server-Sent Event和WebSockets就是其中的两个特性,这两个特性能够帮助我们实现服务器将数据“推送”到客户端的功能。
网页多媒体特性
支持网页端的Audio、Video等多媒体功能, 与网站自带的APPS,摄像头,影音功能相得益彰。
三维、图形及特效特性
基于SVG、Canvas、WebGL及CSS3的3D功能,用户会惊叹于在浏览器中,所呈现的惊人视觉效果。
性能与集成特性
没有用户会永远等待你的Loading——HTML5会通过XMLHttpRequest2等技术,解决以前的跨域等问题,帮助您的Web应用和网站在多样化的环境中更快速的工作。
在不牺牲性能和语义结构的前提下,CSS3中提供了更多的风格和更强的效果。此外,较之以前的Web排版,Web的开放字体格式(WOFF)也提供了更高的灵活性和控制性。而且CSS3的渲染直接使用的GPU加速,对于支持GPU的设备,其动画运行效率相对于JS实现的动画运行效率要提高3倍以上。
HTML5的优缺点
任何技术都有其试用的领域,虽然HTML5已经在很多方面有所改善,但是必须要认清目前HTML5还具有的优缺点。
HTML5的优点
HTML5本身是由W3C推荐出来的,它的开发是通过谷歌、苹果,诺基亚、中国移动等几百家公司一起酝酿的技术,这个技术最大的好处在于它是一个公开的技术。换句话说,每一个公开的标准都可以根据W3C的资料库找寻根源。另一方面,W3C通过的HTML5标准也就意味着每一个浏览器或每一个平台都会去实现
用HTML5的优点主要在于,这个技术可以进行跨平台的使用。比如你开发了一款HTML5的游戏,你可以很轻易地移植到UC的开放平台、Opera的游戏中心、Facebook应用平台,甚至可以通过封装的技术发放到App Store或Google Play上,所以它的跨平台非常强大,也是大多数人对HTML5有兴趣的主要原因。
提高可用性和改进用户的友好体验;
有几个新的标签,这将有助于开发人员定义重要的内容;
可以给站点带来更多的多媒体元素(视频和音频);
可以很好的替代FLASH和Silverlight;
当涉及到网站的抓取和索引的时候,对于SEO很友好;
将被大量应用于移动应用程序和游戏。
HTML5的缺点
浏览器的编程模型还是90年代流行的单进程单线程 (single process single thread),但原生实现(比如用Object C)的APP可以用多线程。移动端编写APP,可以使用多个线程,第一个线程,被称作主线程(main thread),编程的第一原则是don’t do heavy work on main thread。通常只让它处理UI事件等,其他重度的工作让其他背景线程来做。但浏览器只有一个线程,所有的事情都是它干。在台式机上,浏览器编程还没有太多问题,因为够快;但在移动端,这个弊端很明显。
如果你的APP是相对静态的,不需要很多对于照片,多点触摸,多向拉动的处理,那完全可以用HTML5来实现;如果不是,比如信息流的展示,游戏等等,最好还是用原生的去实现。
HTML5实现已经是50%以上的iOS APP的选择。相信随着处理能力的提升,将让移动设备的处理不给力带来的体验底下得到改善。而这种处理能力的提高,很大程度上将取决于低耗电高性能CPU/内存的出现,或者电池技术的极大改善。在这一天到来之前,有可能10%的APP无法应用HTML5来实现。
网络应用开发工程师们在学习新技术的同时需要时刻记住网络安全。HTML5所构建的网页和其他语言编写的网页一样容易泄露一些敏感数据。欧洲网络信息安全机构(European Network and Information Security Agency,ENISA)已经警告说HTML5可能并不够安全。
开发前的准备
使用HTML5进行移动应用开发
,需要先了解在HTML5在与移动应用中属于怎样的一个角色,已经HTML5、JS和CSS3的分工
几个关键性问题
移动应用有其固有的特性,所以下面先来了解几个关键性问题。
如何设计服务端数据
客户端发送请求在移动web设备上查看某个内容。这个请求通常是一个发送到某台服务器上的HTTP请求。通常,会自动生成用户需要的内容。为了将内容加入到APP中通常需要至少两件事情:数据以及怎样使数据变得有意义,或者是我们的HTML5 APP。
随时用HTML5,毫无疑问JSON是很好的一种方式,所以更多的时候我们就是要考虑每一个JSON数据的意义。比如常见的RESTful数据,这就要求数据必须符合一组架构约束条件和原则。
你的降级策略如何
HTML5的跨平台性只是依赖于W3C的标准规范,然而,不同的解析内核对HTML5的处理仍有不同,如何去做到全终端的兼容,特别是Android设备的兼容?
当应用无法按照预想的方式呈现时,能够提供一组隔离代码是最好的撤回策略。换句话说,就是要使代码尽量简洁且不依赖某些特殊的边缘技术——我们称之为优雅的降级。
除此之外,运用于移动应用中的HTML5通常都要依赖于宿主容器,比如:ExMobi、PhoneGap等,如果HTML5本身的效果已经无法接受,可以考虑使用非HTML5的实现方式来代替。
如何处理离线数据
15% 的移动APP启动时设备是脱机。所以你的应用程序需要处理脱机的情况。最初的程序设计时页面的访问当然是需要通过Internet的,但是如果连接端掉了,你的程序应该也能够继续正常运行。当设备连接到网络时,应用程序如何处理用户的数据?为了处理脱机访问的情况,是否可以考虑将所有的数据打包返回?
JS脚本分类
用于移动应用的JS通常需要负责三个功能:混合脚本、核心脚本和设备脚本。
混合脚本可以将开发人员编写的核心脚本与设备SDK连接起来。如果你想使用本地封装器(如 UIWebView和PhoneGap。)将HTML5 app封装起来,那么你需要使用混合脚本。需要针对不同的平台编写不同的混合脚本(phonegap.js是唯一一个支持多个平台的脚本)。
核心脚本是app在所有平台上的通用部分。如果app是通过浏览器访问的,核心脚本也应该使得app看起来像是一个native SDK。你的app需要负责收集和渲染HTML5页面。这个时候使用jQuery这类完整的框架是非常有用的,但是我们建议还是尽量使用微框架。
最后,你需要使用设备脚本模拟本地的行为。 jQTouch是一个很好的例子,它使用jQuery模拟iPhone的本地行为和动作。但是jQTouch无法区分不同设备间的差异,在Android以及其他的移动平台上,它都仍然使用在iOS上采用的方法。这一点受到用户的诟病。因此,可能需要为不同的设备编写单独的设备脚本。
虽然CSS语法本身都是渲染HTML的,但是将CSS分好类可以使代码更清晰明确。
这是开发者用来模拟设备风格的CSS代码。它是用户惯用的语言,普通用户看到这些语言后,能够直接开始执行想要处理的任务,而不用花费时间去学习你的界面。据不完全统计,每个平台上有将近100个独立的界面组件。不推荐开发者自己设计一种新的组件,除非你清楚的知道自己在做什么。
核心主题是应用程序中可以重复利用的部分——那些你需要使用,但不一定会显示在界面的上的内容。我习惯将各种部件单独表示(如复位按钮,布局,排版,颜色,图像),这样就能将这些部件作为我的核心主题。这些主题在不同的平台上都是一样的。比如,你的logo在所有的平台上都是一样的。你的工具栏的颜色总是保持一样的风格。这些组件都可以定义为你的核心主题。当你在不同的设备上使用这些核心主题时,只需要修改相应的设备主题即可。
App主题是专属于某个App的风格组件。许多项目诣在将这些组件整合到一个样式表中。但是,建议还是将你的核心主题和App主题区分开来。这对于debug有很大的帮助。
HTML5移动应用开发技巧
设置屏幕自适应
webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用,它可以设置页面适应屏幕的比例。
1 &meta content=”width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;” name=”viewport” /&
2 &meta content=”yes” name=”apple-mobile-web-app-capable” /&
3 &meta content=”black” name=”apple-mobile-web-app-status-bar-style” /&
4 &meta content=”telephone=no” name=”format-detection” /&
5&meta content=”email=no” name=”format-detection” /&
第一个meta标签表示:强制让文档的宽度与设备的宽度保持1:1,并且文档最大的宽度比例是1.0,且不允许用户点击屏幕放大浏览;
第二个meta标签是iphone设备中的safari私有meta标签,它表示:允许全屏模式浏览;
第三个meta标签也是iphone的私有标签,它指定的iphone中safari顶端的状态条的样式;
第四个meta标签表示:告诉设备忽略将页面中的数字识别为电话号码;
第五个meta标签表示:告诉设备忽略将页面中的邮件地址。
HTML5标签的使用
在开始编写webapp时,建议前端工程师使用HTML5,而放弃HTML4,因为HTML5可以实现一些HTML4中无法实现的丰富的WEB应用程序 的体验,可以减少开发者很多的工作量,当然了你决定使用HTML5前,一定要对此非常熟悉,要知道HTML5的新标签的作用。比如定义一块内容或文章区域 可使用section标签,定义导航条或选项卡可以直接使用nav标签等等。
自适应布局模式
在编写CSS时,我不建议前端工程师把容器(不管是外层容器还是内层)的宽度定死。为达到适配各种手持设备,我建议前端工程师使用自适应布局模式(支付宝 采用了自适应布局模式),因为这样做可以让你的页面在ipad、itouch、ipod、iphone、android、web safarik、 chrome都能够正常的显示,你无需再次考虑设备的分辨率。
块级化a标签
请保证将每条数据都放在一个A标签中,为何这样做?因为在触控手机上,为提升用户体验,尽可能的保证用户的可点击区域较大。而且A可以接收到hover、active等css效果。
学会使用webkit-box
前面我们说过自适应布局模式,有些同学可能会问:如何在移动设备上做到完全自适应呢?很感谢webkit为display属性提供了一个webkit-box的值,它可以帮助前端工程师做到盒子模型灵活控制。
iOS中如何禁止用户选中文字
我们通过CSS指定文字标签的-webkit-user-select属性为none便可以禁止iOS用户选中文字。
如何解决盒子边框溢出
当你指定了一个块级元素时,并且为其定义了边框,设置了其宽度为100%。在移动设备开发过程中我们通常会对文本框定义为宽度100%,将其定义为块级元 素以实现全屏自适应的样式,但此时你会发现,该元素的边框(左右)各1个像素会溢了文档,导致出现横向滚动条,为解决这一问题,我们可以为其添加一个特殊 的样式-webkit-box-sizing:border-用来指定该盒子的大小包括边框的宽度。
iOS中如何禁止用户保存图片/复制图片
元素的-webkit-touch-callout属性,同样为一个img标签指定-webkit-touch-callout为none也会禁止设备弹出列表按钮,这样用户就无法保存\复制你的图片了。
Agile移动应用前端框架
Agile 是一个基于HTML5+CSS3+JS的移动应用开发框架,在体验上尽量接近Native Like,并且同时支持单页模式和多页模式。
Agile不仅仅是一个UI框架,也是一个逻辑处理框架,可以实现页面间、页面内不同容器的动画切换显示,也能实现数据的动态注入,使移动应用代码更简洁、易于维护。
Agile的使用文档请参考:
开发模式介绍
基于HTML5的移动应用开发模式主要有单页模式和多页模式两种。
单页模式(Single-page Application)即在一个HTML5移动应用中只包含一个HTML页面,而不同视图的显示实际是在一个页面中采用动态显隐实现,而其中最重要的技术的就是Ajax,不同视图的获取都是通过Ajax从远程服务器中获取。
也就是说,不同的视图都是一个HTML片段,而不是完整的HTML页面。
在 SPA 模式中,主页面(完整HTML页面)是可以独立加载、更新和替换的一些可视元素的组合(HTML片段)。通过这种方式,可以不必在每次用户操作后重新加载整个页面。在任何时候,都只显示与应用程序当前阶段相关的可视元素和内容。其他所有内容均被隐藏;但只要应用程序流程中需要用到它,它就会显示出来。
使用单页模式开发,通常的页面结构为:
多页模式(Multi-page Application)是相对于单页模式而言,应用中的每一个页面都是一个独立HTML页面,而不是HTML片段。
如果是采用传统的WEB思维,在移动应用中的采用多页模式,则每个页面可能都会重复加载一些数据(JS、CSS、部分HTML代码等),并且用户的前进后退操作都有可能会造成页面的刷新,降低用户体验。
所以,需要采用更加高效的方式将通用的数据缓存,提高每个页面加载速度。
如果一个移动app使用agile开发多页模式的应用,则其页面结构应该是:
使用多页模式开发,通常的页面结构为:
单页模式和多页模式的选择并不是随意,一般当开发框架支持数据的缓存方能使用多页模式,否则建议使用单页模式,而且通常支持多页模式的框架,对单页模式也会有较好的支持。
比如:PhoneGap是一个纯HTML5框架,更多能力封装为JS插件,所以适用于单页模式开发;而ExMobi是一个具有清晰界面结构的移动应用开发框架,除了HTML5也能采用其他方式展示界面,所以适用于多页模式开发,当然,如果有特殊需要,单页模式也是可以支持。
实际上不管是单页模式还是多页模式都各有利弊:
比如单页模式会使一个界面不断加载新的元素而导致界面逻辑复杂和页面膨胀,包括HTML、JS和CSS的命名都需要进行有效管理;
而多页模式由于打开多个页面,使得不同页面间的交互比单页模式稍微复杂一些。
所以,通常多页模式和单页模式按比例组合使用是非常有必要的。相对独立的页面可以使用多页模式,有较多交互的页面采用单页模式。
Agile的页面结构
Agile的基本结构是以Section为单个页面的容器,页面中显示的标题导航header和主体内容Article都位于Section之下,并且各自可以显示需要的内容。比如:
一个HTML页面中如果有多个页面要展示,就需要有多个Section,但是同时只有一个Section在显示,不同页面的显示其实就是Section的切换。
Article是Section中显示主体内容的容器,一个Section中也可以有多个Article,但是同时也只有一个Article在显示,不同的主体内容的切换(类似于Tab页、菜单页等)其实就是Article的切换。
Section(页容器)和Article(局部容器)都是Agile的布局容器。那么,除了Section和Article之外,还有Modal(模态框)、Aside(侧边栏)也是布局容器。当然,还有很多组件比如:标题头、导航栏、列表容器、表单容器、模板容器等。具体可以参考:
布局容器的切换
布局容器的切换就构成了一个webapp是单页模式还是多页模式进行开发的。
Agile中的容器切换都是通过标签属性data-target来设置的,比如要打开一个新的Section,那么写法就是:
&a class=&icon icon-compose pull-right& href=&#mail_section& data-target=&section&&&/a&
容器切换的标签写法
前面我们的写那段代码实际就是通过编写标签来在一个页面中打开新的Section进行显示。
下面的表格显示了不同容器切换的标签写法:
上表中标识为单页的即在一个同一个HTML进行操作的;标识为多页的即在新窗口中进行操作的。所以,使用哪种模式进行开发需要开发者根据实际场景来决定。
容器切换的JS写法
由于写上的标签不够灵活,比如一个页面点击登录按钮一般是需要先进行登录校验再做容器的切换,如果直接在按钮上通过标签进行容器切换,那么将无法进行校验。
所以,其实上一节中介绍的标签写法都有对应的JS实现,主要用于在JS中进行逻辑处理后的容器切换。下表提供了不同容器的JS实现。
数据注入基础
Agile使用的数据注入是采用了artTemplate的native语法来实现的,具体可以参考:
其语法的简单示例:
数据注入的基本思路是以&script&标签作为模板容器,JSON数据作为数据源,将JSON数据注入到模板容器中生成新的HTML代码片段,并用于需要显示的地方。
比如:页面中有一个模板容器:
&script type=&text/html& id=&login_template&&
&div style=&padding:10px 20&&
&div style=&text-align:font-size:20color:#3498DB;font-weight:600;margin:5px 0;&&登录&/div&
&input type=&text& name=&name& placeholder=&用户名& value=&&%=username%&&&
&input type=&password& name=&password& placeholder=&密码& value=&&%=password%&&&
&button class=&button block bg-nephritis white& data-target=&closePopup&&&i class=&icon icomoon-checkmark&&&/i&登录&/button&
可以看到此模板中的用户名和密码的值是需要动态注入的。
假设有个JSON数据:
var data = {‘username’:’nandy007’, ‘password’, ‘psw’};
接下来就可以使用artTemplate进行数据注入:
var html = template(‘login_template’,data);
得到的html变量就是一个HTML片段,可以使用innerHTML放置于他需要显示的地方。
Agile中的数据注入
Agile框架中已经封装了众多的数据注入的方法。主要包含:
比如下面的模板就是一个通用模板:
&script type=&text/html& id=&login_template&&
&div style=&padding:10px 20&&
&div style=&text-align:font-size:20color:#3498DB;font-weight:600;margin:5px 0;&&登录&/div&
&input type=&text& name=&name& placeholder=&用户名& value=&&%=username%&&&
&input type=&password& name=&password& placeholder=&密码& value=&&%=password%&&&
&button class=&button block bg-nephritis white& data-target=&closePopup&&&i class=&icon icomoon-checkmark&&&/i&登录&/button&
假设要注入的数据要放置于id为inject_container的div中:
&div id=&inject_container&&
则使用A.tmpl进行渲染的写法为:
var data = {&username&:&nandy&,password:&111&};
A.tmpl(&#inject_container&,&login_template&,data,&replace&);
比如下面的模板就是一个定向模板:
&script id=&tmpl& type=&text/html& data-replace=&#inject_container&&
&p&您输入的是:&%=text%&&/p&
&div class=&toggle& data-on=&是& data-on-value=&1& data-off=&否& data-off-value=&0&&&/div&
它直接指明了渲染后的HTML片段直接注入到id为inject_container的容器中,并且注入方式是替换,即原来inject_container中的内容会被清除掉,只显示新的HTML片段。
使用A.render可以轻松实现定向模板的注入:
var data = {&text&:&Hello Agile!&};
A.render({tmplId:&#tmpl&,data:data});
&article id=&refresh_article& class=&active&&
&div class=&scroller&&
&div class=&card&&
&ul class=&table-view&&
&li class=&table-view-cell&&这是老数据&/li&
&li class=&table-view-cell&&这是老数据&/li&
&script id=&refresh_template& type=&text/html& data-inject=&true& data-source=&../json/template.json&&
for(var i=0;i&(list||[]).i++){
&li class=&table-view-cell&&&%=list[i].title%&&/li&
&/article&
上面的模板就是一个占位模板,不需要JS函数他即可直接通过data-source指定的数据源注入此模板中,并直接在模板所在的位置中进行显示。
当然,有时候我们还需要动态去刷新此模板中数据的,这时候就可以通过JS去刷新,比如我们给refresh_article初始化的时候添加一个下拉刷新的效果,并且在下拉刷新的回调中进行数据的注入对模板进行刷新:
$(&#refresh_article&).on(&articleload&,function(){
A.Refresh({
selector : &#refresh_article&,
type : &pullDown&,
refreshTip : &&span id=&refresh_time& class=&sliver&&更新于:从未更新&/span&&,
callback : function(){
var scroll =
$(&#refresh_template&).renderBefore(function(html){
$(&#refresh_time&).html(&更新于:&+A.Util.formatDate(new Date(),&MM-dd hh:mm&));
scroll.refresh();
$native.toast(&更新成功&);
在ExMobi中使用Agile
下面就一起动手来操作吧。
几个关键问题
在ExMobi中建议使用的是多页模式开发,并且所有页面都是本地页面。所以有几个关键问题需要提前考虑。
如何进行容器切换
其实前面在介绍容器切换的时候已经列出表格,但是这里还是需要再提醒童鞋们,在ExMobi中多页模式常用的容器切换方法主要有:
在一个新的ExMobi页面中打开HTML5页面:
标签写法:&a href=&#id& data-target=&native& &打开一个HTML5页面&/a&
函数写法:$native.openWebView(href [, el]);
打开一个全新的ExMobi页面:
标签写法:&a href=“*.xhtml& data-target=“exmobi& &打开一个ExMobi页面&/a&
函数写法:$native.openExMobiPage(href [, el]);
如何处理跨域请求
随时用HTML5进行移动应用的开发,所有的请求都可以归到Ajax中,但是使用原生Ajax会有跨域请求的问题,如果使用Zepto或者jQuery解决跨域问题使用JSONP对数据格式也相对复杂化,所以,既然基于ExMobi使用HTML5就可以考虑使用ExMobi中的Ajax。
ExMobi中支持的Ajax主要有:Ajax(走服务端)、DirectAjax(直连)、DirectFormSubmit(直连带附件)三种。为了与Zepto的写法一致,Agile对这三种Ajax请求进行了封装:
用法均与Zepto或者jQuery的$.ajax用法一致。
在Agile中如果涉及跨域请求,可以通过设置参数crossDomainHandler实现:
A.settings.crossDomainHandler = $util.
或者在启动Agile的时候设置,比如:
document.addEventListener(&plusready&, function() {
A.launch({
showPageLoading : false,
isAutoRender : true,
crossDomainHandler : $util.ajax
如何使用本地能力
ExMobi将大部分的本地能力封装成桥接类可以直接在HTML5页面中使用,查看ExMobi客户端二次开发手册中,JS带有
图标的即可在HTML5中直接使用。比如:
但是需要注意的是由于桥接类的加载是有一定时间的,比如是加载完毕后方能调用。检测页面是否加载的事件为plusready。所以,如果要检测桥接类是否加载完毕可通过下面代码实现:
document.addEventListener(&plusready&, function() {
$native.toast(&桥接类加载完毕&);
Agile在ExMobi中的最佳实践
本节主要以数据库方式对接测试的OA系统,使用Agile框架来进行开发。
下面请按照下面的步骤一起开始我们的实践吧。
下载Agile框架
使用Agile前需要到ExMobi官网中下载框架需要的内容。下载地址:
,请下载“Agile核心库”(另外的“ExMobi库”是Agile在ExMobi中的完整示例应用,建议下载部署方便查看效果)。
创建带有Agile的应用插件
在MBuilder中创建一个应用插件,我们这里假设创建的是应用插件的id为agileoa。
基本目录结构如下:
Config.xml文件的配置信息如下:
&?xml version=&1.0& encoding=&UTF-8& standalone=&yes&?&
&config clientversion=&4& scope=&client& devicetype=&all&&
&appid&agileoa&/appid&
&appname&agileoa&/appname&
&description&&/description&
&version&1.0&/version&
&date&&/date&
&homepage src=&res:page/index.xhtml&/&
&faultconfig src=&&/&
&vendor url=&& email=&&&&/vendor&
&access orientation=&port& land=&false& network=&true& gps=&true& camera=&true& certificate=&true&/&
&icon selectedlogo=&res:image/selectedlogo.png& main=&res:image/main.png& logo=&res:image/logo.png&/&
然后将下载下来的Agile框架的压缩包解压出来,可以看到四个目录,分别为agile、exmobijs、ratchet和icomoon,将这几个目录拖到MBuilder中agileoa应用插件的script目录下,比如:
编写启动Agile的JS
如果一个页面要使用Agile,就需要在此页面中启动Agile,在启动Agile的时候可以初始化一些参数。
接下来在script目录下创建一个叫app的目录,并且创建一个叫app.js的文件,如下:
此JS文件需要在任何需要使用Agile框架的页面引入,并且放置于最后一个JS。
编辑app.js的代码如下:
document.addEventListener(&plusready&,function(){
A.launch({
showPageLoading : false,//设置ajax请求是否显示进度条
isAutoRender : true,//设置模板容器是否自动加载
crossDomainHandler : $util.server//设置跨域请求处理函数
}, false);
此代码即通过监听ExMobi的所有桥接类加载完毕后启动(A.launch)Agile。其中初始化了三个参数,请看代码注释。其中$util.server是ExMobi的Ajax请求,此请求经过ExMobi的服务端,所以可以在jsp中编写代码进行拦截处理。
编写入口xhtml页面
ExMobi中的HTML5实际上都必须运行在ExMobi的XHTML页面中的,但是由于Agile框架封装了ExMobi页面的拼接,所以如果使用Agile进行开发,除了第一个页面必须是ExMobi的页面,剩下的开发如果全都基于Agile就都可以完全是HTML页面了。为了方便管理我们也需要创建一个html页面的存放目录。
我们在config.xml中设置应用插件入口地址:res:page/index.xhtml。
接下来我们就在page下创建一个index.xhtml文件和html目录(存放html文件)如下:
编辑index.xhtml文件,在页面中使用webview控件来加载html页面,如下:
&html isbridge=&true&&&!-- 必须设置使用ExMobi的桥接类 --&
&meta charset=&UTF-8&/&
&!-- 隐藏掉ExMobi的标题栏 --&
&title show=&false&&欢迎登陆&/title&
&!-- 引入必要的JS --&
&script type=&text/javascript& src=&res:script/exmobijs/base.js&&&/script&
&script type=&text/javascript& src=&res:script/exmobijs/app.js&&&/script&
&script type=&text/javascript& src=&res:script/exmobijs/utility.js&&&/script&
&script type=&text/javascript& src=&res:script/exmobijs/browser.js&&&/script&
&script type=&text/javascript& src=&res:script/exmobijs/bridge.js&&&/script&
&!-- 对body进行必要设置pagedrag(page页是否可以手势切换),pageanimation(page页的动画效果) --&
&body id=&body& pagedrag=&false& pageanimation=&none& pagebackanimation=&none& style=&margin:0;padding:0;&&
&!-- 使用webview作为HTML5的宿主容器,backmonitor(是否拦截返回键,android有效) --&
&webview id=&browser& url=&res:page/html/login.html& backmonitor=&true&&&/webview&
这里有几个点需要注意,在ExMobi的页面中需要设置:
必须在ExMobi的html标签设置isbridge=&true&,目的是在webview中的html页面可以使用ExMobi的本地能力。
在head中必须要引入ExMobiJS框架。
Body中要设置取消动画,并且设置内外边距均为0,可以让html页面铺满整个ExMobi页面。
Webview中设置backmonitor=&true&,在android上可以拦截返回按钮点击的事件。
编写第一个html页面
在上一节中,我们只是创建了入口页面,此入口页面中的webview的url指向地址为:res:page/html/login.html。我们只有编写了此页面在入口页面中才会显示内容。
下面才真正开始使用Agile框架。
我们在html目录点击右键-》新建-》其他,如下:
在弹出的对话框中选择web下的html,如下:
然后点击“下一步”,在对话框中修改文件名为“login.html”如下:
点击“完成”按钮即可完成页面的创建。
页面会自动打开,我们编辑页面,开始使用Agile框架,代码如下:
&!DOCTYPE html&
&!-- 设置必要的meta信息 --&
&meta charset=&utf-8&&
&meta name=&viewport& content=&initial-scale=1, maximum-scale=1, user-scalable=no&&
&!-- 引入必要的css --&
&link rel=&stylesheet& href=&../../script/ratchet/css/ratchet.css&&
&link rel=&stylesheet& href=&../../script/ratchet/css/ratchet-theme-ios.css&&
&link rel=&stylesheet& href=&../../script/agile/css/agile.css&&
&link rel=&stylesheet& href=&../../script/icomoon/icomoon.css&&
&div id=&section_container&&&!-- section的容器,id必须为section_container --&
&section id=&login_section& class=&active&&
&header class=&bar bar-nav&&
&a class=&icon icon-left-nav pull-left& data-target=&close& href=&#&&&/a&
&h1 class=&title&&欢迎登陆&/h1&
&article class=&active&&
&form style=&padding:10px 6&&
&input type=&text& id=&username& name=&username& placeholder=&请输入用户名& value=&admin&&
&input type=&password& id=&password& name=&password& placeholder=&请输入密码& value=&111&&
&a id=&btn_login& class=&btn btn-primary btn-block&&登陆&/a&
&/article&
&/section&
&!-- 引入必要的JS --&
&script type=&text/javascript& src=&../../script/exmobijs/bridge.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/zepto.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/iscroll.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/agile.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/agile.exmobi.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/touch2mouse.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/template-native.js&&&/script&
&!-- 启动Agile --&
&script type=&text/javascript& src=&../../script/app/app.js&&&/script&
//设置点击登录按钮后的操作
$(&#btn_login&).click(function(){
var username = $(&#username&).val();
var password = $(&#password&).val();
if(username==&&){
$native.toast(&请输入用户名&);
}else if(password==&&){
$native.toast(&请输入密码&);
$util.server({
url : &http://oa/checkLogin.jsp&,
type : &post&,
data : &username=&+username+&&password=&+password,
dataType : &json&,
success : function(data){
if(data.result==&success&){
$native.openWebView(&main.html&);
$native.toast(&登录失败&);
error : function(){
$native.toast(&登录异常&);
页面中一些关键的部位都做了注释,建议仔细阅读。主要关注编码、meta屏幕宽度设置以及必要的css和JS文件的相对地址以及引用顺序。
另外需要注意的Agile页面的结构,也就是基于Section的页面结构。头部、底部、主题部位如何显示。需要更深入了解的同学请到Agile的文档中心查看相关组件
我们在页面中给登录按钮设置了点击事件,当点击按钮的时候会去校验用户名密码是否已经输入,根据判断进行登录请求的操作。
我们重点关注一下登录请求,这是一个Ajax请求,走了ExMobi的服务端,请求的url地址为
,是一个虚拟地址;而且使用post方式提交了参数username和password;在成功和失败回调中根据响应结果做判断。
为了能够使此请求能够经过ExMobi的服务端,根据ExMobi服务端智能匹配原则,我们直接在server目录下创建checkLogin.jsp文件即可做到,如下:
在编辑checkLogin.jsp之前,我们需要做一个数据库资源的配置,因为我们在接下来的代码中都需要与数据库交互,所以在server下的mapp.xml中进行数据库配置如下:
&?xml version=&1.0& encoding=&UTF-8& ?&
&maxml version=&2.0& xmlns=&http://www..cn/map&
xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance&
xsi:schemaLocation=&http://www..cn/map maxml-2.0.xsd&&
&htmlformat wellformat=&true& /&
&filepreviewconfig wordtohtml=&true&/&
&database id=&postgresql& dbtype=&postgresql& ip=&miap.cc& port=&1006& dbname=&app& user=&sitest& password=&123456& maxconn=&10& minconn=&2& defconn=&5& /&
接下来,编辑checkLogin.jsp对数据库进行操作,通过提交的用户名和密码查找是否有用户存在,然后返回json数据给客户端进行进一步的逻辑判断,代码如下:
&%@ page language=&java& import=&java.util.*,com.fiberhome.mon.util.*&
contentType=&application/uixml+ charset=UTF-8& pageEncoding=&UTF-8&%&
&%@ include file=&/client/adapt.jsp&%&
String username = aa.req.getParameter(&username&);
String password = aa.req.getParameter(&password&);
String sql = &select * from tbl_user where username=&&+username+&& and password=&&+password+&&&;
&aa:sql-excute dbId=&postgresql& sql=&&%=sql %&& id=&checkLogin&&&/aa:sql-excute&
{result:&&%=(aa.xpath.xpath(&//result/@size&, &checkLogin&).equals(&1&)?&success&:&fail&)%&&}
该jsp响应的结果是一个形如{result:’success|fail’}的一个json数据,那么在html页面的Ajax回调函数中就可以通过获取该json数据进行逻辑判断。
页面显示结果如下:
如果登录成功就跳转到主页中,这里涉及一个在JS中进行容器切换,使用的是$native.openWebView(&main.html&),其含义是在一个新的ExMobi页面中使用webview打开main.html页面。
编写主页html页面
本节重点要了解一下数据注入的用法。
首先在html目录下创建main.html页面,并编辑页面代码如下:
&!DOCTYPE html&
&!-- 设置必要的meta信息 --&
&meta charset=&utf-8&&
&meta name=&viewport& content=&initial-scale=1, maximum-scale=1, user-scalable=no&&
&!-- 引入必要的css --&
&link rel=&stylesheet& href=&../../script/ratchet/css/ratchet.css&&
&link rel=&stylesheet& href=&../../script/ratchet/css/ratchet-theme-ios.css&&
&link rel=&stylesheet& href=&../../script/agile/css/agile.css&&
&link rel=&stylesheet& href=&../../script/icomoon/icomoon.css&&
&div id=&section_container&&&!-- section的容器,id必须为section_container --&
&section id=&main_section& class=&active&&
&header class=&bar bar-nav&&
&a class=&icon icon-left-nav pull-left& data-target=&close& href=&#&&&/a&
&h1 class=&title&&查询&/h1&
&div class=&bar bar-standard bar-header-secondary&&
&input type=&text& id=&search& placeholder=&请输入关键字& style=&margin-top:2&&
&article id=&query_article& class=&active& data-scroll=&true&&
&div class=&scroller&&
&ul class=&table-view&&
&script id=&query_template& type=&text/html& data-inject=&true& data-source=&http://oa/query.jsp?search=${$(&#search&).val()}&&
for(var i=0;i&(list||[]).i++){
&li class=&table-view-cell&&&a href=&detail.html?id=&%=list[i].id%&& data-target=&native&&&%=list[i].title%&&/a&&/li&
&/article&
&/section&
&!-- 引入必要的JS --&
&script type=&text/javascript& src=&../../script/exmobijs/bridge.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/zepto.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/iscroll.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/agile.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/agile.exmobi.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/touch2mouse.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/template-native.js&&&/script&
&!-- 启动Agile --&
&script type=&text/javascript& src=&../../script/app/app.js&&&/script&
$(&#search&).change(function(){
$(&#query_template&).renderReplace(function(){
//A.Element.scroll(&#query_article&);//可以在回调中写一些后续的处理逻辑
此页面中使用了一个id为query_template的占位模板,因为它设置了data-inject=”true”,也就是说此模板被渲染后的数据均注入到此模板所在的位置上;渲染使用的数据定义在data-source中,这个data-source使用了${JS表达式}的形式,可以看到此JS表达式实际是去获取搜索框的值,需要把此值作为查询条件。这样模板容器在加载的时候就会自动进行数据的请求、渲染和注入了。
另外需要关注的是,当搜索框的内容被改变的时候,在底部的script中监听了此事件,并且使用$(&#query_template&).renderReplace的方法来刷新容器,从方法上看刷新的方法是替换方式的,并且可以给其设置回调函数。在回调函数中做一些注入后续的处理操作。
这里有个小贴士,占位模板刷新的时候很多时候data-source通常都是动态的,这里就动态获取了搜索框的值,有时候还需要进行复杂的分页的运算,这时候如果需要刷新模板注入,可以通过指定url来实现,比如上面刷新的代码就可以改成:
$(&#search&).change(function(){
var url = &http://oa/query.jsp?search=&+$(&#search&).val();
$(&#query_template&).renderReplace(url,function(){
//A.Element.scroll(&#query_article&);//可以在回调中写一些后续的处理逻辑
但是需要注意的是如果占位模板一旦设置data-source,那么第一次注入的时候默认是从data-source取数据的,如果不写data-source的话第一次就不会注入。后面的数据刷新,如果没有重置url,则默认从data-source取数据,如果写了url则从指定的url取数据,如果既不写data-source也不指定url将不进行注入。
模板中我们通过遍历list变量(数组)来循环显示列表数据的,所以接下来我们需要在query.jsp中查询数据库组成一个键为list,值为一个数组的json对象,代码如下:
&%@ page language=&java& import=&java.util.*,com.fiberhome.mon.util.*&
contentType=&application/uixml+ charset=UTF-8& pageEncoding=&UTF-8&%&
&%@ include file=&/client/adapt.jsp&%&
String search = aa.req.getParameterFromUrl(&search&);
String sql = &select * from tbl_task where title like &%&+search+&%& limit 20&;
System.out.println(sql);
&aa:sql-excute dbId=&postgresql& sql=&&%=sql %&& id=&query&&&/aa:sql-excute&
&aa:for-each var=&item& xpath=&//datarow& dsId=&query&&
title : &&%=aa.xpath.xpath(&./datacol[@name=&title&]&, &item&)%&&,
id : &&%=aa.xpath.xpath(&./datacol[@name=&id&]&, &item&)%&&
&/aa:for-each&
最终页面展示效果如下:
从模板中,我们可以看出,每个列表数据点击后都会触发data-target=”native”的操作,也就是在一个新的ExMobi页面中打开一个html页面,此html页面的地址在href中,形如detail.html?id={id值},可以看出传递了一个参数为id。
下面我们继续编写详情页面。
编写详情html页面
首先在html目录下创建detail.html页面,代码如下:
&!DOCTYPE html&
&!-- 设置必要的meta信息 --&
&meta charset=&utf-8&&
&meta name=&viewport& content=&initial-scale=1, maximum-scale=1, user-scalable=no&&
&!-- 引入必要的css --&
&link rel=&stylesheet& href=&../../script/ratchet/css/ratchet.css&&
&link rel=&stylesheet& href=&../../script/ratchet/css/ratchet-theme-ios.css&&
&link rel=&stylesheet& href=&../../script/agile/css/agile.css&&
&link rel=&stylesheet& href=&../../script/icomoon/icomoon.css&&
&div id=&section_container&&&!-- section的容器,id必须为section_container --&
&section id=&detail_section& class=&active&&
&header class=&bar bar-nav&&
&a class=&icon icon-left-nav pull-left& data-target=&close& href=&#&&&/a&
&h1 class=&title&&详情&/h1&
&article id=&detail_article& class=&active& data-scroll=&true&&
&div class=&scroller&&
&script id=&detail_template& type=&text/html& data-inject=&true& data-source=&http://oa/detail.jsp?id=${$native.getParameter(&id&)}&&
&form class=&input-group&&
&div class=&input-row&&
&label&标题&/label&
&input type=&text& name=&title& value=&&%=title %&&&
&div class=&input-row&&
&label&开始时间&/label&
&div data-role=&date&&
&label&请选择日期&/label&
&input type=&hidden& name=&begin_time& value=&&%=begin_time %&& /&
&div class=&input-row&&
&label&结束时间&/label&
&div data-role=&date&&
&label&请选择日期&/label&
&input type=&hidden& name=&end_time& value=&&%=end_time %&& /&
&div class=&input-row&&
&label&任务执行人&/label&
&input type=&text& name=&executor& value=&&%=executor %&&&
&div class=&input-row&&
&label&优先级&/label&
&input type=&text& name=&priority_level& value=&&%=priority_level %&&&
&div class=&input-row&&
&label&任务说明&/label&
&textarea rows=&4& name=&remark& value=&&%=remark %&&&&/textarea&
&/article&
&/section&
&!-- 引入必要的JS --&
&script type=&text/javascript& src=&../../script/exmobijs/bridge.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/zepto.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/iscroll.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/agile.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/agile.exmobi.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/touch2mouse.js&&&/script&
&script type=&text/javascript& src=&../../script/agile/js/template-native.js&&&/script&
&!-- 启动Agile --&
&script type=&text/javascript& src=&../../script/app/app.js&&&/script&
这里同样也有一个占位模板,此模板的data-source是
,这里也用到了${JS表达式},此表达式的是获取上一个页面中传递过来的参数,也就是id值,这样在detail.jsp中就可以得到此id值并以此作为查询条件查询详情信息。
下面在server中创建detail.jsp文件,并编辑代码如下:
&%@ page language=&java& import=&java.util.*,com.fiberhome.mon.util.*&
contentType=&application/uixml+ charset=UTF-8& pageEncoding=&UTF-8&%&
&%@ include file=&/client/adapt.jsp&%&
String sql = &select * from tbl_task where id=&&+aa.req.getParameterFromUrl(&id&)+&&&;
&aa:sql-excute id=&selectOne& dbId=&postgresql& sql=&&%=sql %&&/&
title : &&%=aa.xpath(&//datacol[@name=&title&]&, &selectOne&) %&&,
begin_time : &&%=aa.xpath(&//datacol[@name=&begin_time&]&, &selectOne&) %&&,
end_time : &&%=aa.xpath(&//datacol[@name=&end_time&]&, &selectOne&) %&&,
executor : &&%=aa.xpath(&//datacol[@name=&executor&]&, &selectOne&) %&&,
priority_level : &&%=aa.xpath(&//datacol[@name=&priority_level&]&, &selectOne&) %&&,
remark : &&%=aa.xpath(&//datacol[@name=&remark&]&, &selectOne&) %&&
它返回了一个JSON对象,包含了表单详情需要显示的一些信息。
最终页面展示下过如下:
从上面的开发过程来看,使用HTML5的开发与ExMobi应用的开发的思路基本上是一样的,只是封装的内容不同。
但是使用Agile开发HTML5应用也有自己的特点:
对于使用Agile开发的HTML5应用,除了第一个页面是XHTML页面,其他页面均为HTML页面(当然可以跳转HTML5再打开其他的XHTML页面);
Agile的使用需要引入必要的CSS和JS文件,并且Agile的使用需要先启动,启动的顺序是在ExMobi的桥接类加载完毕后进行;
Agile的页面切换是依赖于Agile布局容器的data-target属性来指定的,需要知道各类容器的打开方式,以及其模式是单页还是多页;
Agile数据处理的核心在于数据注入,而重中之重又是跨域请求,也就是ExMobi几种Ajax的使用。比如需要走ExMobi的服务端就使用$util.server;
不同页面间的传值通过$native.getParameter来实现,除此之外,还可以使用ExMobi的session和cache来实现。

我要回帖

更多关于 html5 原生 的文章

 

随机推荐