Agile Lite内部的组件和控制器默认是不工作做的,只有当AL启动之后才会正常工作。

Agile Lite的启动主要是完成控制器和组件的初始化。启动后,页面会默认显示第一个具有active样式的section组件以及此section下的第一个具有active样式的article组件。

AL启动函数为,A.launch(options)。其中options启动项包含:


agileReadyEvent : 'agileready',//AL正确启动后触发的事件名称
readyEvent : 'ready', //触发AL启动的事件,默认为ready,即页面加载完成,如果处于特定宿主容器中,建议使用宿主容器的加载事件
backEvent : 'backmenu', //宿主容器的返回按钮事件
crossDomainHandler : null, //跨域请求的处理类,一般用于提供了网络请求类的宿主容器中,一般浏览器中不需要设置
showPageLoading : false, //section页面加载是否显示进度条
viewSuffix : '.html', //加载静态文件的默认后缀
lazyloadPlaceholder : '', //懒人加载的默认图片
usePageParam : true, //单页模式是否记录section页面访问参数,此参数通过base64编码记录,会比较长;多页模式建议设置为false
pageParamEncode : false,//是否对hash记录的参数信息进行编码
autoInitCom : true, //是否默认初始化组件,默认为true初始化,可以设置为false不初始化,目前初始化的操作有数据注入和popup打开时
iScrollOptions : {}, //设置IScroll默认配置项
mode : 'single', //页面模式,默认是单页模式,可选值single(单页)/muti(多页),多页的时候url无hash
                

典型的AL启动如下:


A.launch({
    readyEvent: 'ready'
});
                

需要注意的是,AL的启动是个异步的过程,所以不能在调用launch之后立即就调用AL的组件或者控制器,而是应该在等待AL启动完毕之后才能调用。

AL启动完毕会往document触发A.options.agileReadyEvent事件,所以,如果希望页面以进来就要调用控制器就需要监听此事件进行。或者监听第一个section的sectionload事件做这些事情,同理,监听article的articleload也可以。

Agile Lite的控制器用于各个组件之间的切换,所以控制器与组件密不可分。

比如:控制不同页面的切换、tab控制article的显示,页面的关闭等等都属于控制器的范畴。

控制器默认的控制效果就是组件的显隐,被控制的组件通常为一组,同一组中的组件仅有一个处于显示状态(active样式),其他的处于隐藏状态(无active样式)。

调用控制器

控制器有两种调用方式,一种是标签方式:定义了data-toggle="控制器"的元素即为控制器;另一种是JS调用A.Controller.控制器()

如果为标签方式,控制器控制的组件通常写在href属性中,href的值有两种形式,#id和url,比如:href="#index_article"或者href="index_article.html?a=1"

特别的,#id是直接与被控制的组件id关联的,而url形式则是通过url的文件名(不含后缀)和组件的id关联的,比如上面的index_article.html?a=1中,文件名就是index_article,也就是说它要控制的组件的id必须为index_article。

但并不是每个控制器的写法都是一样的,具体需要参考各个控制器的用法。

以article控制器为例:

1、标签方式调用示例:

控制器写法,设置了data-toggle的即为控制器:


<a class="tab-item active" data-role="tab" data-toggle="article" href="#flat_article">
    <span class="icon icon-pages"></span>
    <span class="tab-label">FlatUI</span>
</a>
                

从data-toggle的值可以看出它控制的对象是一个article,从控制器的href中可以看出article的id必须是flat_article,如下:


<article data-role="article" id="flat_article" data-scroll="verticle" class="active" style="top:44px;bottom:50px;">
    <div class="scroller">
    </div>
</article>
                

此article必须设置data-role="article"指明自己是article组件。这样就完成了一个控制器控制组件的示例。

2、JS方式调用示例:

有的时候我们需要在做一些js逻辑操作后再执行控制器,这时候就需要通过JS来调用控制器,控制器调用的方法都是统一的A.Controller.控制器(),比如切换某个article:


A.Controller.article('#flat_article');
                

控制器传参

当控制器需要给组件传参的时候,控制器的href只能为url形式,而不能为#id形式。

而组件获取参数的方式则是通过A.Component.params(selector)来调用,此方法得到的是一个参数的json对象。

比如有一个article如下控制器:


<a class="menu" data-role="tab" href="second_article.html?id=1&title=Agile框架实战" data-toggle="article">
    <span class="menu-icon iconfont iconline-notebook"></span>
    <span class="menu-text">Article</span>
</a>
                

可以看出其需要打开一个article,并传了两个参数id和title,假设要打开的article如下:


<article data-role="article" id="second_article" data-scroll="verticle" style="top:44px;bottom:56px;">
    <div class="scroller">

    </div>
</article>
                

那么,我们如果希望在article显示的时候通过id和title等进一步获取不同的数据加入到article中展示,则可以参考如下代码:


$('#second_article').on('articleload', function(){
    var params = A.Component.params(this);//获取所有参数,此处为{'id':'1', 'title':'Agile框架实战'}
    A.showToast('参数id的值为:'+params.id);
});
                

1.1.2版本之后原获取参数的方法$(selector).data('params')已经无法继续使用,升级到此版本之后的请统一使用A.Component.params(selector)

控制组件缓存

被控制器控制的组件是可以异步加载的,但是默认第一次加载之后,后面再次显示此组件的时候是不会再次去加载的。但是有时候是需要重新去加载这些的数据,以刷新界面的展示。

这时候可以通过给组件设置data-cache="false"在取消组件的缓存,当组件被控制隐藏的时候会被remove出dom结构,从而下次再控制显示的时候会重新加载数据。

比如:


<article data-role="article" id="second_article" data-scroll="verticle" data-cache="false" style="top:44px;bottom:56px;">
    <div class="scroller">

    </div>
</article>
                

但是需要注意的是,data-cache="false"一般仅对异步加载的组件使用,如果是对dom中已经存在的组件使用,则当其hide的时候也会被remove出dom结构中,而当下一次调用show的时候又无法异步获取则可能会导致页面显示异常。

Agile Lite是一个无关UI的框架,所以任何独立CSS的UI都可以在Agile Lite中使用,但并不是所有用于Agile Lite的UI是可以被控制器控制的组件。

只有设置了data-role的元素才能被控制器控制。

组件自身可以控制自己,默认效果就是自身(组件)的显隐,组件通常为一组,同一组中的组件仅有一个处于显示状态(active样式),其他的处于隐藏状态(无active样式)。

也可以通过组件的自定义实现更多的非显隐的效果。

组件的初始化

默认的组件的初始化可以通过A.Component.组件名(匹配组件的选择器)来实现。

比如:初始化datetime组件即为:A.Component.datetime('#date)

当然,也会有一些特殊组件的初始化方式不同,具体根据各个组件的定义来。

一般的组件默认初始化是在articleload的时候完成的,如果组件是异步加载的大多需要自行进行初始化,而Agile Lite的数据注入的回调中可以返回注入的HTML片段的$对象,所以如果使用Agile Lite的数据注入就可以很方便的对这部分$对象做初始化,比如:


$('#main_article').on('articleload', function(){
    A.template('#template').renderReplace(data, function(h, o){
        A.Component.datetime(h);//h为注入的数据片段对应的$对象
    });
});
                

组件的生命周期事件

通过控制器控制打开的组件,如果继承了默认的view控制器,都会有生命周期事件(包括load、show、hide三个)。

不同组件的生命周期事件不同,但是都是有规律的,即:控制器名称+事件名,比如section控制器控制的section组件具有sectionload、sectionshow和sectionhide事件。

load、show、hide的含义分别如下:

load:当组件第一次显示时候触发的事件(显示的含义是可见,已经加载但是尚未显示则不会加载),下一次显示的时候则不再触发。特别的,当组件设置了data-cache="false"的时候,下一次再打开组件,load事件会触发。

show:组件每一次显示的时候触发的事件,只要组件从非active状态转为active状态均会触发。

hide:组件每一次隐藏的时候触发的事件,只要组件从active状态转为非active状态均会触发。

目前具有此生命周期的组件有:viewsectionarticlemodalaside(无load),以及继承了view默认控制器的组件(扩展或者重写控制器时如果没有设置‘handler’处理函数选项即继承view默认控制器)。

获取组件对象和函数

如果一个组件封装有自己的扩展函数,则可以先通过var com = A.Component.getObject(组件名, 组件hash)来获取组件对象。

然后通过com.函数名([参数])来调用这些扩展函数。

比如,日期时间组件扩展了清空选择的函数clear,则调用的方法为:


var com = A.Component.getObject('datetime', '#date');
com.clear();
                

组件转场动画切换

组件切换的时候默认都是有转场动画效果的,而组件的显示和隐藏的动画通常是成对、相反效果出现的。

如果需要设置组件的切换动画效果,可以给组件设置data-transition来设置。其取值范围包括:

empty:同时作用于当前切换的两个组件,显隐均无动画

slide:同时作用于当前切换的两个组件,左滑显示,右滑隐藏

cover:仅作用于要显示的组件,隐藏的组件无动画,左滑显示,右滑隐藏

slideUp:仅作用于要显示的组件,隐藏的组件无动画,上滑显示,下滑隐藏

slideDown:仅作用于要显示的组件,隐藏的组件无动画,下滑显示,上滑隐藏

如果开发者需要使用自己的动画效果可以对动画进行扩展。扩展方式为在AL启动之前通过A.anim.addClass(cssObj)方法来添加样式。

其中cssObj是一个json对象,形如:


{
    key : [
            [currentOut,targetIn],//进入动画组
            [currentOut,targetIn]//后退动画组
          ]
}
                

比如Section的默认动画为slide : [['slideLeftOut','slideLeftIn'],['slideRightOut','slideRightIn']]

假设A Section打开B Section。则A为current,B为target,打开的时候A的动画为slideLeftOut隐藏,B的动画为slideLedtIn显示。

当后退的时候,B为current,A为target,B的动画为slideRightOut隐藏,A的动画为slideRightIn显示。

控制器的工作原理很简单,满足以下条件即可:

1、控制器的data-toggle的值与组件的data-role的值一致;

2、控制器的href值与组件的id“同名”。

所谓同名,控制器的href值只能有两种形式:

1、#id形式,这时候此id必须跟组件的id一致;比如:


<!--- 控制器 --->
<a href="#tab1" data-toggle="article">tab</a>
<!--- 组件 --->
<article id="tab1" data-role="article">
</atricle>
                

2、url形式,这时候url的文件名(不含后缀)必须与组件的id一致。比如:


<!--- 控制器 --->
<a href="tab2.html?a=1" data-toggle="article">tab</a>
<!--- 组件 --->
<article id="tab2" data-role="article">
</atricle>
                

同时,控制器必须加载完毕,而组件则可以异步加载。控制器在本页中未找到“同名”id的组件时,如果为#id形式,则会在同级目录找同名的html文件,即id.html并异步加载进来;如果是url形式,则会异步加载url请求的结果。

控制器的默认效果就是控制组件的显隐的切换。目前已经内置的控制器有:html、section、article、modal、aside、back。

view默认控制器

Agile Lite中有一个默认控制器,此控制器就是实现组件的基本显隐,没有过多的效果。

一般能用其他控制器的时候可以用其他控制器,只有在暂时不满足需求的时候要做组件的显隐操作可以用此控制器。

比如:


<div class="segmented-control">
    <a class="control-item active" data-role="tab" data-toggle="view" href="#view1">One</a>
    <a class="control-item" data-role="tab" data-toggle="view" href="#view2">Two</a>
</div>
<div>
    <div id="view1" data-role="view" class="active">这是view1</div>
    <div id="view2" data-role="view">这是view2</div>
<div>
                

开发者可以自行给相应的组件添加自定义的css来再美化。

html控制器

html控制器是实现多页模式的控制器,当处于浏览器或者微信等不支持多页模式的宿主容器时,其效果即为location.href打开新页面。

当处于ExMobi等支持多页模式的宿主容器时,开发者可以重写此控制器达到使用宿主容器的多窗口机制。

用法:

打开:A.Controller.html('#id|url')

关闭:A.Controller.back()

section控制器

section控制器是实现单页模式的控制器。section组件在Agile Lite为页容器,也就是说占满屏的组件,所以此控制器的效果就跟原生APP的页面之间的切换效果,达到模拟原生交互的目的。

用法:

切换:A.Controller.section('#id|url')。section只可切换,当新的section被打开的时候,同级的section就处于关闭状态

事件:sectionload、sectionshow、sectionhide

其他:section组件支持设置data-require="modules",其中modules为需要require.js引入的模块,多个模块用英文逗号分隔,当组件首次被加载(sectionload)的时候会同时require所有的modules

article控制器

article控制器是实现单页模式的控制器。article组件顾名思义就是页面主体内容,除了菜单和导航之外的数据一般都放置与article中,article组件的控制效果则类似于页面内部不同界面的切换。

用法:

切换:A.Controller.article('#id|url')。article只可切换,当新的article被打开的时候,同级的article就处于关闭状态

事件:articleload、articleshow、articlehide

modal控制器是实现单页模式的控制器。所谓modal组件就是模态页,主要用于辅助一个页面的交互,一般用于某个页面的附属页面,比如发送邮件的选人页面就可以是modal组件。

用法:

打开和关闭:A.Controller.modal('#id|url')。modal的打开和关闭都是相同的,当打开的时候调用则关闭,当关闭的时候调用则打开

事件:modalload、modalshow、modalhide

aside控制器

aside控制器是实现单页模式的控制器。aside组件是侧边栏组件,与section位置平行,通常aside组件是作为section组件的子模块显示,最常见的就是侧边栏菜单。

用法:

打开:A.Controller.aside('#id', callback)。在页面中只能有一个aside打开。

关闭:A.Controller.aside(callback)

事件:无触发事件,但是可以在js调用的时候设置回调。

back控制器

back控制器是实现单页模式的控制器。其效果是返回上一个控制器的状态。在多页模式中,可以监听返回事件关闭html页面所在的窗口。

用法:A.Controller.back(json)

当back的组件是一个section的时候,json将作为参数传递给section,通过A.Component.params(#sectionId)可以获取到这个json对象。其余情况请勿使用json参数。

page控制器

page控制器通常是与slider组件一起工作,作为slider组件内的某个slide,可以被其他组件调用。实现滑动页的切换效果。

用法:A.Controller.page('#id')

事件:slidershow、sliderhide

nativepage控制器

nativepage控制器用于打开一个原生的窗口页,比如在ExMobi中就是打开一个uixml页面,而如果是其他的宿主容器则需要宿主容器提供相应的方法,开发者重写此控制器。

用法:A.Controller.nativepage('res:page/{path}.uimxl')。其中path为uixml文件所在page目录下的路径。

事件:当要打开一个uixml并传参的时候,比如:res:page/main.uixml?user=nandy的时候,在新打开的uixml中就可以通过$native.getParameter('user')获取到。

前面提到html控制器可以被重写以支持多页模式的宿主容器,那是因为Agile Lite提供了控制器重写的接口。

重写的方法为:A.Controller.add(controllerObj)

controllerObj的对象形式为:


{
    controller : {
        selector : '[data-toggle="controller"]',//[必选]控制器对应的选择器
        container : '',//[可选]被控制的组件所处于的容器选择器,用于当组件异步加载的时候
        isToggle : false,//[可选]控制器是否仅目标组件控制,默认是false,即处理控制目标对象,也控制与被控制组件同级的组件,为ture则仅控制目标组件
        handler : function(hash){//[可选]若无此函数,则走默认的控制器处理函数,如果有此函数,则需要自行处理所有逻辑,包括异步加载和事件触发等

        },
        complete : function(hash){//[可选]若有此函数则handler处理完毕会进入此函数

        },

    },
   // ......更多控制器
}
                

比如:在ExMobi里重写html控制器如下:


A.Controller.add({
    html : {
        selector : '[data-toggle="html"]',
        handler : function(hash, el){
            try{
                ExMobiWindow;
                var $el = $(el);
                var isBlank = $el.attr('target')=='_self'?false:true;
                var transition = $el.data('transition')||'';
                $native.openWebview(hash, isBlank, transition);
            }catch(e){
                location.href = A.util.parseURL(hash).getURL();
            }

        }
    }
});
                

所有控制器都可以通过A.Controller.控制器(#id|url)来调用

组件的效果不近相同。有的组件是实现滚动效果,有的组件是实现下拉刷新效果,组件相对更灵活。

其中的scroll、refresh和slider组件均是通过IScroll5实现的(具体为其中的iscroll-probe.js细分类),所以这几个组件必须符合IScroll的三层架构,即wrapper、scroller、container三部分。

关于IScroll5,推荐大家阅读IScroll5中文API建议参考手册

这几个组件自身就是一个wrapper,所以在显示内容的时候必须再嵌套一个div,Agile Lite已经定义好样式为.scroller,具体请看各个组件示例。

scroll组件

scroll组件用于控制容器的滚动情况。本质是依赖于IScroll5实现。

  • 用法
  • data-scroll="verticle|horizontal|scroll"
  • 说明
  • verticle:纵向滚动条
  • horizontal:横滚动条
  • scroll:纵向、横滚动条
  • 初始化/获得Scroll组件对象(同时也是IScroll对象)
  • articleload的时候默认初始化
  • 手动初始化调用var scroll = A.Scroll('#id');//得到一个scroll组件(其类型为iscroll对象)
  • 多次调用不会重复初始化,只能获取组件对象本身。如需重新初始化可以调用IScroll的destroy函数后才能重新初始化。
  • 事件
  • 使用方法:scroll.on('event',function);
  • event支持ISroll的所有事件
  • 扩展支持:scrollInit、scrollTop和scrollBottom

比如:


<article data-role="article" id="main_article" data-scroll="verticle" class="active" style="top:44px;bottom:0px;">
    <div class="scroller">

    </div>
</atricle>
                

可以通过如下事件对此scroll组件进行监听和操作:


//当scroll初始化会进入此监听
$('#main_article').on('scrollInit', function(){
    var scroll = A.Scroll(this);//已经初始化后不会重新初始化,但是可以得到滚动对象
    //监听滚动到顶部事件,可以做一些逻辑操作
    scroll.on('scrollTop', function(){
        A.showToast('滚动到顶部');
        //scroll.refresh(); //如果scroll区域dom有改变,需要刷新一下此区域
    });
    //监听滚动到底部事件,可以做一些逻辑操作
    scroll.on('scrollBottom', function(){
        A.showToast('滚动到底部');
        //scroll.refresh(); //如果scroll区域dom有改变,需要刷新一下此区域,
    });
});
                

注:

1、 一般当Article为scroll组件的时候,都是通过监听scroll初始化事件(scrollInit)而不是监听articleload或者articleshow事件,因为前者通常比后者晚触发,所以如果需要异步加载数据可能会出现scroll组件尚未初始化的情况,所以一般建议在scrollInit中执行注入等操作。

2、由于scroll组件是继承于IScroll,所以当scroll组件内部空间大小有变化时需要刷新scroll组件以适应新的空间大小。方法为scroll.refresh()。

refresh组件

refresh组件是实现下拉和上拉刷新的一个组件。也是依赖于IScroll5。

  • 用法
  • data-scroll="pull|pulldown|pullup"
  • 说明
  • pull:上下拉均出现
  • pulldown:仅出现下拉
  • pullup:仅出现上拉
  • 初始化/获得Refresh组件对象(同时也是IScroll对象)
  • articleload的时候默认初始化
  • 手动初始化调用var refresh = A.Refresh('#id')//得到一个refresh组件(其类型为iscroll对象)
  • 多次调用不会重复初始化,只能获取组件对象本身。如需重新初始化可以调用IScroll的destroy函数后才能重新初始化。
  • 事件
  • 使用方法:refresh.on('event',function);
  • event支持ISroll的所有事件
  • 扩展支持:refreshInit、pulldown、pullup、scrollTop和scrollBottom
  • 方法
  • 扩展支持:refresh.setConfig(opts)函数,此函数是设置上拉和下拉“三态”属性(普通状态、释放状态、刷新状态),有默认值,可不设置。
    其中opts形如:
    
    {
        pullDownOpts : {//下拉刷新显示内容配置
            normalLabel : '继续下拉',//普通状态
            releaseLabel : '可以啦可以啦',//释放状态
            refreshLabel : '终于松开啦'//刷新状态
        },
        pullUpOpts : {//上拉刷新显示内容配置
            normalLabel : '上拉试试',//普通状态
            releaseLabel : '有完没完',//释放状态
            refreshLabel : '哎呦我去'//刷新状态
        }
    }
                                

比如下面的article设置data-sroll="pull":


<article data-role="article" id="main_article" data-scroll="pull" class="active" style="top:44px;bottom:0px;">
    <div class="scroller">

    </div>
</article>
                

可以通过以下方法进行事件监听:


//当refresh初始化会进入此监听
$('#main_article').on('refreshInit', function(){
    var refresh = A.Refresh('#main_article');
    //监听下拉刷新事件,可以做一些逻辑操作,当data-scroll="pullup"时无效
    refresh.on('pulldown', function(){
        $('#content').prepend('<li><div class="text">下拉刷新的内容</div></li>');
        refresh.refresh();//当scroll区域有dom结构变化需刷新
    });
    //监听上拉刷新事件,可以做一些逻辑操作,当data-scroll="pulldown"时无效
    refresh.on('pullup', function(){
        $('#content').append('<li><div class="text">上拉刷新的内容</div></li>');
        refresh.refresh();//当scroll区域有dom结构变化需刷新
    });
});
                

注:

1、一般当Article为refresh组件的时候,都是通过监听refresh初始化事件(refreshInit)而不是监听articleload或者articleshow事件,因为前者通常比后者晚触发,所以如果需要异步加载数据可能会出现refresh组件尚未初始化的情况,所以一般建议在refreshInit中执行注入等操作。

2、由于refresh组件是继承于IScroll,所以当refresh组件内部空间大小变化时需要刷新refresh组件以适应新的空间大小。方法为refresh.refresh()。

slider组件

slider组件用于滑动块的显示。

  • 用法
  • Silder组件不会自动初始化,可以使用A.Slider(#id, opts)方式调用,此方法同时也是获得slider组件的方法,其返回一个IScroll对象。
    
    var slider = A.Slider(#id);//此处返回个IScroll对象,可以通过此对象调用IScroll的相关方法
                                    
  • opts说明
  • opts对象包括:auto、loop、dots和change几个参数
  • auto:true|false|number,是否自动播放,默认false
  • loop:true|false,是否循环滚动,默认false(当slider组件内是data-page组件,则此选项一定为false,不可修改)
  • dots:center|left|right|hide,焦点的位置,默认center
  • change:函数,slider切换后的回调函数,默认接受参数为当前slide的位置

slider可以互相嵌套,当某个slider的宽度和高度均为100%(屏幕大小)时则可以实现类似于滑动页的效果。

下面是一个最简单的slider示例。假设有如下slider:


<div id="slide" data-role="slider" class="full" style="height: 230px;">
    <div class="scroller">
        <div class="slide">
            <img src="assets/app/img/slide1.jpg" class="full-width"/>
            <div class="slider_label">综合新闻</div>
        </div>
        <div class="slide">
            <img src="assets/app/img/slide2.jpg" class="full-width"/>
            <div class="slider_label">综合新闻</div>
        </div>
        <div class="slide">
            <img src="assets/app/img/slide3.jpg" class="full-width"/>
            <div class="slider_label">综合新闻</div>
        </div>
    </div>
</div>
                

则初始化的方法如下:


$('#main_article').on('articleload', function(){
    A.Slider('#slide', {
        dots : 'right'
    });//得到一个slider组件(其类型为IScroll对象)
});
                

注:

slider组件不可重复初始化,如果内部dom结构有变化(比如增加或者删除slide),需要先调用slider组件对象的destroy函数再重新初始化。

lazyload组件

lazyload是懒人加载组件。

  • 懒人加载介绍
  • 懒人加载即是对图片的延迟加载,目的是节约资源、提高性能

  • 懒人加载用法
  • 只需要给img添加data-source属性指向实际的图片地址即可

  • 注意事项
  • 请不要设置img的src属性,可以设置placeholder指定默认图片

  • 初始化状态
  • 当articleload的时候会自动初始化懒人加载

  • 手动初始化
  • 手动初始化A.Component.lazyload($el)即可

popup弹窗组件主要是实现模拟原生alert、confirm、loading、actionsheet、toast、popover等。

除了loading弹出窗外,其他弹出窗均可同时存在多个实例。所以在使用loading的时候请通过逻辑控制仅有一个实例。

alert(确认提示框):A.alert(title,content)

confirm(询问提示框):A.confirm(title,content,okCallback,cancelCallback)

loading(加载进度条):A.showMask()与A.hideMask()

actionsheet(菜单组):A.actionsheet(btns[, showCancel|cancelCss])

toast(自隐提示框):A.showToast|alarmToast(content)

popover(跟随提示框):A.popover(btns)

closePopup(关闭提示框):A.closePopup(),关闭最上层的一个popup

其中,btns是一个按钮对象数组,此按钮对象形如:


{
    text : '按钮显示的文字',
    css : '按钮样式', //非必须
    handler : function(){
        //点击按钮处理的逻辑
    }
}
                

也可自定义:A.popup(options)

options支持如下:


var options = {
    id : '',//[可选]弹出窗的id,相同的弹出窗将不会重复初始化
    html : '',//位于pop中的内容
    pos : 'center',//[可选]pop显示的位置和样式,top|bottom|center|left|right|custom
    css : {},//[可选]自定义的样式
    isBlock : false//[可选]是否禁止关闭,false为不禁止,true为禁止,默认为false
};
                

上述提供的popup能力实际都是A.Popup函数的简化用法,此函数提供了popup的核心功能。

A.Popup函数的使用必须通过new实例化,即:new A.Popup(options)来实现。其中opts的参数跟A.popup的参数一致,即:


var options = {
    id : '',//[可选]弹出窗的id,相同的弹出窗将不会重复初始化
    html : '',//位于pop中的内容
    pos : 'center',//[可选]pop显示的位置和样式,top|bottom|center|left|right|custom
    css : {},//[可选]自定义的样式
    isBlock : false//[可选]是否禁止关闭,false为不禁止,true为禁止,默认为false
};
                

A.Popup提供如下函数操作弹出窗:

open(callback):打开弹出窗,并在打开后调用callback回调函数。

close(callback):关闭弹出窗,并在关闭后调用callback回调函数。

on('popupopen|popupclose', callback):监听弹出窗事件仅支持popupopen和popupclose,监听到则调用callback回调函数。

A.Popup提供如下监听事件:

popupopen:当弹出窗打开后的触发,this对象为Popup对象本身。

popupclose:当弹出窗关闭后的触发,this对象为Popup对象本身。

需要注意是的,Popup对象本身可以通过Popup.popup来获取到当前弹出窗的$DOM对象。

下面是一个实例化A.Popup函数的示例:


var $popup = new A.Popup({
    html: '这是一个来自顶部的弹出框',
    pos : 'top',
}).on('popupopen', function(){
    A.showToast('打开的时候提示');
}).on('popupclose', function(){
    A.showToast('关闭的时候提示');
}).open(function(){
    //this对象就是A.popup对象,this.popup就是弹出窗的$DOM对象
    //alert(this.popup.html());//得到就是弹出窗的代码片段
    A.showToast('打开的时候提示');
});
setTimeout(function(){
    //手动关闭弹出窗
    $popup.close();
}, 2000);
                

另外,在弹窗内任意组件添加data-toggle="popup"控制器,可以控制关闭此弹出窗。

tab组件

tab组件一般用于顶部的和底部的菜单切换,以标注某个菜单的选中状态。

其标签用法为data-role="tab"添加到指定的组件中即可,比如:


<div class="tabbar">
    <a class="tab active">tab页</a>
    <a class="tab">tab页</a>
    <a class="tab">tab页</a>
</div>
                

tab组件默认在articleload的时候初始化,异步加载的tab组件可以使用A.Component.tab(hash)

formcheck组件

formcheck组件是对checkboxradio组件进行操作的组件。主要是美化checkbox和radio样式。

其标签写法分别为data-role="checboxk"data-role="radio"

formcheck组件会在articleload和数据注入之后自动初始化,如果开发者不是调用Agile Lite的数据注入进行异步添加此组件,需要自己手动初始化。

手动初始化的方法为:A.Component.formcheck(hash)

toggle组件

toggle组件是类似于ios系统的开关按钮效果。

其标签写法为设置data-role="toggle",同时可以支持设置开和关两个状态显示的文本和取值。比如:


<div class="toggle" name="toggle"  data-role="toggle" data-on="是" data-on-value="1" data-off="否" data-off-value="0" style="margin-top:4px;"></div>
                

需要注意的是,toggle是一个自定义的表单组件,如果需要其提交值,则需要给此组件对应的标签添加name属性,这时候Agile Lite会自动在此组件下创建一个与此name相同的input标签,最终提交的是此input标签的值。

另外,当需要默认设置toggle显示的是选中状态请为此组件添加active样式,反之则去掉active样式

跟formcheck组件一样,toggle组件在articleload和数据注入之后默认初始化,手动初始化请使用A.Component.toggle(hash)

toggle组件的状态切换也是A.Component.toggle(hash)

toggle组件的取值$('toggle组件selector input').val(),比如:$('[name="toggle"].toggle input').val()

toggle组件每次切换均会触发datachange事件。

scrollTop组件

scrollTop组件用于控制data-scroll滚动组件区域内容滚动到顶部。

其初始化方式为data-role="scrollTop",并且必须指定href="hash",其中hash为被控制的data-scroll组件的#id。

比如:


<a data-role="scrollTop" data-toggle="scrollTop" href="#flat_article" style="bottom:56px;right:4px;">
    <img src="assets/app/img/top.png" style="border: 1px solid #efefef;"></img>
</a>
                

aside组件

aside组件主要是为扩展aside控制器而提供的,默认aside控制器是通过JS来控制aside和section的移动动画的。

但是通过JS控制动画会存在在低端机运行不流畅的问题。

增加的aside组件,通过给aside设置data-role="aside"即可,它将使aside的动画采用CSS3的方式移动,提高运行的性能,但是可能会在浏览器内核较低的机器上不支持CSS3。

pictureShow组件

pictureShow组件是一个类似于网易新闻客户端的图片新闻内容的展示。支持多个图文信息左右切换滑动显示。

此组件只能通过JS来调用:A.Component.pictureShow(options)

其中,options形式如下:


{
    id : '页面的id',//pictureShow组件实际会创建一个section页容器展示。页容器的id即为此id值,section控制器的所有操作都适合
    index : 数字,//默认显示的图文信息的索引号,从0开始
    header : 'html代码',//默认header只显示一个X点击会关闭组件,可以自己写html代码来代替这个X显示
    title : '新闻标题',//每一帧显示的图文信息中显示的标题
    list : [
        {
            imgURL : 'http://bbs.exmobi.cn/data/attachment/block/25/254961a7ddb3a4c97fdc9336d396925e.jpg',//当前帧显示的图片地址
            content : 'ExMobi以其开放、标准、灵活的特性让开发者可以快速使用成熟组件开发,也能自己扩展个性化的原生组件'//当前帧显示的新闻内容
        }
    ]
}
                

具体效果可查看此链接,点击slider图片。点击链接

这里列举一些已经扩展的组件。

datetime组件

时间选择组件的使用需要引入Agile Lite以及agile.timepicker.js和timepicker.css,如果需要自动初始化,需要引入相应的extend.js,并且在标签中加入data-role="date"或者data-role="time"。

初始化

非自动初始化时,需要语句来调用组件。 var picker = A.Timepicker(option);var picker = A.Datepicker(option);

初始化选项

时间选择器的初始化选项格式为:


                    option:{
                    hasSecond:true,//选择内容是否有秒
                    isCustomLeftButton:true,//是否自定义左侧按钮
                    customLeftButtonName:’name’,//左侧按钮名称
                    customLeftButtonCallback:callback,//左侧按钮点击回调
                    onStart:callback,//选择开始回调
                    onSelected:callback//选择完毕回调
                    }
            
日期选择器初始化选项格式为:

                    option:{
                    isCustomLeftButton:true,//是否自定义左侧按钮
                    customLeftButtonName:’name’,//左侧按钮名称
                    customLeftButtonCallback:callback,//左侧按钮点击回调
                    onStart:callback,//选择开始回调
                    onSelected:callback//选择完毕回调
                    }
                

内置函数

开始选择:select(selectedDate, callback)

selectDate为Date对象,是控件显示时的日期。


                    callback是选择完毕时的回调,回调数据格式如下:
                    {
                    date: _full_date,//选中的时间,为Date对象
                    dateString: _date_string,//选中的日期字符串,格式为’2015-6-22’
                    timeString: _time_string//选中的时间字符串,格式为’09:06:30’
                    fullString: _full_string//选中的日期时间字符串,格式为’2015-6-22 09:06:30’
                    }
            

组件扩展函数

获取组件方法:var com = A.Component.getObject('datetime', hash)

内置函数:

com.clear();//清空已选的值

com.open();//打开日期时间选择器

事件:

datetime组件每次选择均会触发datachange事件。

calendar组件

日历组件的使用需要引入Agile Lite以及agile.calendar.js和calendar.css。显示日历的div需要加上data-role="calendar",以及需要id属性。

初始化

var calendar = A.Calendar("#id",option);其中id是需要显示日历的div的id,option是初始化的选项。

初始化选项


                {
                show_day: new Date(),//日期类型,用于初始化当前选中日期
                marks: {},//标识对象,详见表3-1数据格式
                row: 6,//日历显示行数
                startRow: null,//选择月显示开始行数
                autoJump: true//选择日期时是否自动跳转至选择月
                }
                

内置函数

方法格式

功能

详情

onTap(callback)

设置用户选择日期时的回调

 

回调数据格式:{

    date: date_data,//点击日期对应的日期对象

    mark: marks_array,//点击日期对应的标志对象

    element: $target//当前点击的日期DOM元素

}

refresh(level, callback)

刷新日历

level表示刷新级别:

0表示刷新标志

1表示刷新日期布局

2表示重新绘制日历

onChange(callback)

监听年月改变

回调数据格式:{

    selectedYear: date_data,//改变后显示的年份

    selectedMonth: marks_array,//改变后显示的月份

}

goto(data, callback)

跳转至日期

data为日期数据,Date对象

monthJump(step, callback)

月份跳转

step为跳转步数,是整数,也可以为负数

addMarkData(date_string, data)

添加一个标志

date_string为日期的字符串,格式为’2015-6-22’

data为单个数据。

setMarkAllData(date_string, data)

设置日期数据

date_string为日期的字符串,格式为’2015-6-22’

data为数据集合数组。

getMarkAllData(date_string)

获得日期所有数据

date_string为日期的字符串,格式为’2015-6-22’

返回数据集合数组。

getMark(date_string)

获得特定日期标志

date_string为日期的字符串,格式为’2015-6-22’

返回标志对象。

setMark(date_string,data)

设置特定日期标准

date_string为日期的字符串,格式为’2015-6-22’

data标志对象。

removeMarkAllData(date_string)

移除日期标志所有数据

date_string为日期的字符串,格式为’2015-6-22’

removeMark(date_string)

移除标志

date_string为日期的字符串,格式为’2015-6-22’

数据格式

名称

描述

详情

marks

标志集合

格式:{

   ‘2015-6-22’:mark

}

mark

标志

格式:{

data:[],//数据集合数组

formClass:’样式名’,

top:{

        ontent:内容',

        class:’顶部内容样式名

},

bottom:{

        ontent:内容',

        class:’底部内容样式名

},

hideCount:true//是否在日历上隐藏数据计数

}

滑动列表

列表滑动组件的使用需要引入Agile Lite以及agile.exlist.js和exlist.css,并且使用需要配合Agile Lite 的ul.listitem来使用

初始化

初始化分两种,针对ul的和针对li的。
var liController = A.ExList.liController('.li_class',option);
var ulController = A.ExList.liController('#ul_id',option);

初始化选项


                option:{
                leftContent:’html’,//左侧内容的html
                rightContent:’html’//右侧内容的html
                }
                

初始化选项

方法格式

功能

详情

showLeft()

显示左侧内容

左侧内容默认为checkbox

hideLeft()

隐藏左侧内容

右侧内容默认为删除按钮。

refresh()

刷新组件

在添加修改li之后需要进行刷新操作。

组件也是可以重写的,那是因为Agile Lite也提供了组件重写的接口。

重写的方法为:A.Component.add(componentObj)

componentObj的对象形式为:


{
    component : {
        selector : '组件所在的父容器的选择器',
        event : '父容器的某个事件',
        isToggle : boolean,//[非必须]是否为单组件,true为单组件仅对自身有效,false对同组组件有效,默认为false
        handler : function(el, roleType){//父容器的事件出发后执行组件的初始化函数
        extend : {
                    funcName : function(){
                        var $el = $(this);//扩展的函数内的this指向组件的$对象本身
                    }
            }
        },
        // ......更多组件
    }
}
                

比如:在ExMobi里重写文件选择组件如下:


A.Component.add({

    file : {
        selector : '[data-role="article"].active',
        event : 'articleload',
        handler : function(el, roleType){
            var $el = $(el);
            var _work = function($el){
            var $label = $el.find('label');
            var $input = $el.find('input');
            var placeholder = $label.html();
            $el.tap(function(e){
                $native.openFileGroupSelector(function(str){
                    str = str?str.join(';'):'';
                    if(str&&($input.val()!=str)&&$el.data('change')){
                        eval($el.data('change'));
                    }
                    $label.html(str?str:placeholder);
                    $input.val(str||'');
                });
                return false;
            });
            $label.html($input.val()||placeholder);
            };

            if($el.data('role')=='file'){
                _work($el);
            }else{
                 var components = $el.find('[data-role="file"]');
                 for(var i=0;i<components.length;i++){
                    _work($(components[i]));
                 }
             }
        },
        extend : {
            open : function(){
                var $el = $(this);//获得file组件对象
                $el.trigger(A.options.clickEvent);//触发组件的click事件
            }
        }
    }
});
                

这时候可以通过var com = A.Component.getObject('file', hash);获得组件,通过com.open()来调用扩展函数open。

所有组件都可以通过A.Component.组件(#id)来初始化

Agile的数据注入是依赖于与artTemplate的。目的是达到界面与数据分离,方便代码的维护。

模板的定义方式为为script元素设置type="text/html",模板的数据可以写于script元素体中,也可以设置到src属性中指向本地的一个html文件。

渲染模板

渲染模板即将一个json对象渲染到模板中形成新的HTML代码片段,此代码片段则可以自行控制加到其他dom对象中。

其方法为:A.template('#templateId').render(json);

其中templateId为某个模板的id,json为要注入的数据。此方法最终会返回一个html片段,比如:


var html = A.template('#template').render({list:['Agile Lite移动前端框架', 'ExMobi三大引擎完美融合']});
$('#content').append(html);
                

占位模板

占位模板即是将某个模板放置于要显示的位置,当往模板注入数据的时候,渲染后的数据即在模板所在的位置进行展示,不需要手动放置于某个dom中。

其方法为:A.template('#id').renderReplace|renderBefore|renderAfter(data, callback)

从方法上可以看出其意思是将data数据注入到某个id的模板中,注入的方式可以是替换模板所在的位置|在模板之前注入|在模板之后注入。

而callback为注入后的回调函数,此函数接受两个参数,第一个参数为注入后的dom对象,第二个参数为注入前的data数据。

假设我们要实现一个功能,当article上拉和下拉的分别数据注入到模板中,代码如下:


<article data-role="article" id="main_article" data-scroll="pull" class="active" style="top:44px;bottom:0px;">
    <div class="scroller">
        <ul id="content" class="listitem">
            <li class="sliver">介绍</li>
            <li>
            Agile Template是基于artTemplate的模板注入封装
            </li>
            <li class="sliver">基本用法</li>
            <li>
            A.template('#templateId').renderReplace|renderBefore|renderAfter(url|data,callback);
            </li>
            <li class="sliver">下拉或上拉刷新查看效果</li>
            <script id="template" type="text/html">
            <% for (i = 0; i < list.length; i ++) { %>
            <li>条目内容 <%= i + 1 %> :<%= list[i] %></li>
            <% } %>
            </script>
        </ul>
    </div>

</article>
                

则可以通过如下JS进行操作:


$('#main_article').on('refreshInit', function(){
    //首次进来加载使用replace
    //A.template('#template').renderReplace('${$config.exmobiSevice}/render');
    A.template('#template').renderReplace('json/template.json');

    var refresh = A.Refresh('#main_article');
    refresh.on('pulldown', function(){
        //下拉刷新加载到前面用before
        A.template('#template').renderBefore({list:['Agile Lite移动前端框架', 'ExMobi三大引擎完美融合']},function(h){//h为渲染后的dom对象
            refresh.refresh();
        });
    });

    refresh.on('pullup', function(){
        //上拉刷新加载到后面用after
        A.template('#template').renderAfter({list:['Agile Lite移动前端框架', 'ExMobi三大引擎完美融合']}, function(){
            refresh.refresh();
        });

    });
});
                

Agile Lite中封装了两种ajax,而exmobi.js中则封装了ExMobi的4种ajax。

A.ajax

此函数是对$.ajax的一个简单封装,用法与$.ajax类似。此处不做详细介绍。

A.util.ajax

此方法很重要,一般做多端开发都建议使用此方法来实现ajax异步请求。

此函数主要是对跨域做了多重的处理。当在启动Agile Lite时如果设置了crossDomainHandler跨域请求处理类指向一个外部的跨域处理函数,则当跨域的时候就会通过此函数来处理。

其原因是jQuery或者Zepto处理跨域都是通过jsonp来实现的,而原生宿主容器,比如ExMobi等则有自己的http请求处理类,其不存在跨域问题,如果在这些容器中使用Agile Lite则不需要使用jsonp。

所以通过在启动时设置跨域请求处理类就可以使用此类来处理跨域。比如在启动的时候设置如下:


A.launch({
    readyEvent : 'plusready',//触发ready的事件,在ExMobi中为plusready
    backEvent : 'backmonitor',
    crossDomainHandler : function(opts){
        $util.ajax(opts);
    }
});
                

那如果Agile Lite用于一个本地的html页面,需要访问一个http网络请求,就属于跨域访问,这时候就会走到这里设置的$util.ajax函数来处理,这是exmobi.js封装的ExMobi直连请求。

而对于非跨域的请求则继续走A.ajax函数。

A.util.ajax的参数也是与$.ajax相似。

A.util.getHTML

此函数是对A.ajax类的进一步封装,即获取同域的text文本内容,所以是不可以跨域的。一般在一个html页面获取同级的另一个html页面或者其他文本文件都可以用此方法。

其参数有两个,一个是url,一个是callback回调。比如:


A.util.getHTML('./test.html', function(h){
    //h即为获取到的文本内容,可以用于注入,或者innerHTML等
    $('#content').html(h);//往id为content的容器中设置内容
});
                

exmobi中的ajax

exmobi.js的桥接类中,提供了$util.ajax(opts)$util.server(opts)$util.form(opts)$util.serverForm(opts)4种实现网络http请求的方式。

函数参数描述
$util.ajax opts 为json对象{url,type,data,success,error,isBlock} 该请求实际调用的是ExMobi的直连DirectAjax,与ExMobi服务端无关
$util.server opts 为json对象{url,type,data,success,error,isBlock} 该请求实际调用的是ExMobi的Ajax服务端路由处理,可以使用ExMobi服务端的路由拦截处理
$util.form opts 为json对象{url,type,fileElementId,data,success,error,isBlock} 该请求实际调用的是ExMobi的DirectFormSubmit,与ExMobi服务端无关,主要用于带文件的表单提交。fileElementId用于设置存储了文件信息的对象id
$util.serverForm opts 为json对象{url,type,fileElementId,data,success,error,isBlock} 该请求实际调用的是ExMobi的FormSubmit服务端路由处理,主要用于带文件的表单提交。fileElementId用于设置存储了文件信息的对象id

在看Agile Lite示例代码的时候,我们经常会看到${...}的一些内容,这里说的内置变量就是指包含在${}之间的内容。其目的是通过变量的方式动态还原内置变量的值。

内置变量必须是一个全局变量,或者是一个全局的json对象。比如:

href="${$config.exmobiService}/login.action"就要求必须有一个json对象:$config.exmobiService,比如:


var $config = {
    exmobiSevice : '${$native.getAppSetting().domain}/process/service/${ClientUtil.getAppId()}'
};
                

由此可以看出一个内置变量里也是可以继续包含另一个内置变量的。

目前内置变量主要用于url中,Agile Lite封装的所有Ajax方法在请求一个包含内置变量的url时都会自动去解析其值,还原实际的url地址。

除此之外,Agile Lite在数据注入之后也会对渲染后的HTML片段自动还原内置变量。

由于Agile Lite框架的滚动组件使用的是iscroll5,而大部分的展示的内容都是在滚动组件内的,所以点击事件的处理需要特别注意。

因为AL使用iscroll的默认配置如下:


var options = {
    mouseWheel: true,
    scrollbars : 'custom',
    fadeScrollbars : true,
    //click : true,
    preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL|A|IMG)$/ }
};
                

也就是说click事件是被阻止的,所以包括所有标签的onclick事件,A的href跳转等都有可能不被执行。

另外,基于目前主流的开发模式,在代码中写事件方式也是不允许的。所以AL框架在的所有事件均需要采用监听方式绑定

特别的,AL根据设备是否支持触摸提供了一个变量A.options.clickEvent供click监听事件调用,当支持触摸时其值为tap,当不支持触摸时其值为click。并且回调函数内要使用return false;阻止事件冒泡。

比如,我们要给一个A监听事件:


$('a.button').on(A.options.clickEvent, function(){
    /* your code*/
    //可以通过给A添加自定义属性,在事件中获取,比如var id = $(this).data('id');//需要给A添加data-id="XXX"自定义属性
    return false;
});
                

如果是做html的URL地址跳转,我们一般直接给A加href,这时候也是被阻止的,可以考虑使用html控制器,即:给A添加data-toggle="html"属性。

另外,对于是在无法改变在属性写onclick事件的开发者,AL里提供了data-click属性,此属性值会在元素被点击的时候作为函数触发(eval实现)。比如,传统的onclick="handle()"不会被触发,但是写为data-click="handle()"会被触发。

如果开发者对iscroll有研究,知道比较确切的通过配置iscroll参数来解决点击问题,也可以通过给滚动组件添加data-scroll-options来重置AL初始化iscroll的参数,比如:


<article data-role="article" id="flat_article" data-scroll="verticle" data-scroll-options="{preventDefaultException: { tagName: /^(.*)$/ }}" class="active" style="top:44px;bottom:50px;">
    <div class="scroller">
    </div>
</article>
                

可以看出,通过data-scroll-options属性重置了preventDefaultException的初始化配置项。具体可以修改的配置项请参考iscroll5相关API。