AppWorker教程-基础-组件概述

组件是AppWorker的基础,平台根据Android,IOS的SDK抽象了一套统一的javascirpt库,把所有组件分三种类型(UI,MM,SM),这三种组件都有自己的属性,事件,方法,其他所有组件(目前大概有200)都是这三种组件的子类,继承了父类的属性,事件和方法。应用开发者只需要了解基本的javascipt知识和我们提供的这套API规范,就可以开始开发移动应用了。

AppWorker目前只支持ES5标准,缺省只支持原生JS函数。

1. UI/SM/MM的简介

  • UI(User Interface) : 页面上的控件,只要能放在页面展示出来的,能在设计器中可视化编辑属性的,就是UI. 如 Button 、 ImageView、 Label 等.

  • SM(Singleton Modle) : 单例的组件,主要实现对原生单例API的封装, 如 Global 、 App、 Page、 Storage 、 Device 等.这些组件在整个app中就只有一个对象.它的方法更像是我们其它语言常用的静态方法。

  • MM(Multiton Modle) : 多实例组件, 对原生的多实例API的封装. 如 SQLite 、 Http 、 Animation 等.在整个app中可以new多个对象。

我们提供了3个对应的工厂方法以获取或构建UI/SM/MM的实例.

  • ui() : 通过UI对象的id来获取对象,id是一个ui对象的id属性值。这个id值由开发者来定义,可以是任何字符串

注意:ui函数只在ui.js里执行才有意义,因为ui函数的执行是需要对应的ui文件上下文的。

    var button = ui("button-id");
    var imageview = ui("imageview-id");
    var listview = ui("listview-id1");
    var label = ui("aaa");
  • sm() : 通过SM组件的名称来构建对象,不过因为是单例,只有第一次调用sm函数是构建,以后再调用就是获取已经构建好的对象了
    var camera = sm("do_Camera");
    var app = sm("do_App");
    //在整个App任何时刻任何位置打印sm对象的地址都是唯一的
    print(app.getAddress());

注意:do_Page是特殊的sm对象,但是实例并不唯一,其它文档有相关介绍

  • mm() : 通过MM组件的名称,id以及作用域来创建或者获取对象。每次执行一次mm函数都会创建一个实例对象。
    比较特殊的是就是可以创建一个作用域在App级别的对象,这个对象可以在App其它地方获取到整个对象。
    var http1 = mm("do_Http");//缺省在当前page作用域
    var httpaddress1 = http1.getAddress();
       
    //创建一个作用域在App级别的do_Http组件的对象,它的id是http_id1,如果在这个作用域里已经有这个id的对象,则不会创建新的,而是返回已有的对象
    var http2 = mm("do_Http","http_id1","app");
    var httpaddress2 = http2.getAddress();// httpaddress1 != httpaddress2

    var animation = mm("do_Animation","anim_id1","page");//等同于 var animation = mm("do_Animation");

    var http3 = mm("do_Http","http_id1","app");
    var httpaddress3 = http3.getAddress();// httpaddress2 == httpaddress3

2. 属性

UI/MM 都定义了属性. 其中ui的属性可以在设计器的可视化界面里直接修改,属性值保存在.ui文件里。
属性的访问和设置通过js代码有以下的两种访问方式:

  • 以属性名访问

    var button = ui("button-id");   //获取实例
    var txt = buttton.text;         //获取Text属性
    button.text = "设置Text属性"     //设置Text属性

    var bgc = button.bgColor;       //获取bgColor属性
    button.bgColor = "#FFFFFFEE"    //设置bgColor属性

  • 以get/set方法访问属性
    var button = ui("button-id");          //获取实例
    var txt = buttton.get("text");         //获取Text属性
    button.set("text", "设置Text属性")      //设置Text属性

    var bgc = buttton.get("bgColor");      //获取bgColor属性
    button.set("bgColor", "#FFFFFFEE");    //设置bgColor属性

    /*** get/set 方法可批量 获取/设置 ***/
    var g = button.get(["text", "bgColor"]); // g == {text : "获取Text属性", bgColor : "#FFFFFFEE"};
    button.set({text : "设置Text属性", bgColor : "#FFFFFFEE"});

MM的属性访问方式与UI完全一致.

UI类型的属性还分为二种类型,OnlyDesign和Always

  • Always:表示可以通过脚本代码来设置,如上面的示例代码,也能通过设计器的属性设置界面来设置。
  • OnlyDesign:表示只能通过设计器的属性设置界面来设置,不能通过代码来动态修改。

3. 方法

UI/SM/MM 都具有方法.并且,方法包含两种类型 : 同步方法/异步方法

  • 同步方法:同步方法一般执行非耗时操作,立即返回执行结果.如 UI/MM 的 get/set 都属于同步方法.

    var global = sm("do_Global");
    global.setMemory("str0", {demo : [1,2,3,4]});
    var str0 = global.getMemory("str0");
    //setMemory/getMemory 执行结束立即返回结果, 都是同步方法.
    //更多详见各个模块的API.
  • 异步方法:异步方法一般是因为需要执行耗时操作,操作结束后会调用注册的回调函数,并将结果以回调函数的第一参数返回.异步方法的最后一个参数是一个回调函数(function);
    var storage = sm("do_Storage");
    storage.getFiles("data://demo/", function(data){
        //data == ["aaa.txt","bbb.json", "ccc.x"];
    });
    //更多详见各个模块的API.

所有方法的调用都有两种调用格式

  • 多参数平铺调用(以上的示例都是这样的)
  • 参数哈希式(双参数式)
    //假设 : 函数 Do.demo 有4个参数 a, b, c, d 和 回调 f , 并且 c, d 两个参数可选:
    //0. 参数平铺:
        Do.demo( a, b , c , d , f)
        Do.demo( a, b , c , f)
        Do.demo( a, b , f)

    //1. 散列式:
        Do.demo({
            a : a,
            b : b,
            c : c,
            d : d
        }, f)
        Do.demo({
            a : a,
            b : b,
            c : c
        }, f)
        Do.demo({
            a : a,
            b : b
        }, f)

    //以App.openPage 具体说明一下
    var app = sm("do_App");
    do_app.openPage(
            "source://view/index.ui",  //要打开的页面路径
            { demo : [1,2,3,4] },      //要传递的数据
            "fade",                    //过场动画类型
            "default",                 //打开页面后的键盘模式
            function(data ,e){
                /*do something*/
            });
    /*****************************************************************

  *以上就是全参数式, 这样的写法参数的顺序要严格按照 API 给定的顺序输入.
  *如果是异步方法, 最后一个参数应是回调函数.

  *****************************************************************/

    //上面的例子中, 除了第一个参数( 要打开的页面路径 ) 外, 其他参数都可选.
    app.openPage("source://view/index.ui", function(data){
        /*do something*/
    });

    //上面的的例子简洁了许多. 但是如果需求是要求写入大量的参数,明显这种方式的可读性还是很差的.

    //所以我们也为这样的需求量身定做了第二套调用方案:
    app.openPage( {
              source : "source://view/index.ui",
              data : "",
              animationType : "",
              keyboardMode : "default"
          },
          function(data ,e){
                /*do something*/
          });

     // 这种方案增强了代码的可读性,第一个参数是一个hash表, (如果是异步方法 第二个是一个回调函数)
     // 注意, 回调函数不能放在第一个参数当中...
    //可以根据自己的喜好和习惯自行选择.

4. 事件

UI/SM/MM 都定义了事件. 每个组件所支持的事件都在组件API上做了阐述.

比如:
do_Button : touch/touchUp/touchDown
do_Page : loaded
....

UI/SM/MM 事件的订阅/触发/注销 都是同样的规则.

  • 订阅事件 [ .on() ]:订阅的事件可以是API支持的事件(touch/touchUp), 也可以是自定义的事件( touch001 / touch002 )
    var button = ui("button-id");
    //订阅button 的touch事件.(手指点击页面此Button时触发, 或通过fire 方法手动触发.)
    button.on("touch", function(){
        /*do something*/
        this.bgColor = "#FF00FFFF";
        // this == button;
    });

    //订阅button 的touch001事件.( 只能通过 fire 触发 );
    buttoon.on("touch001", function(){
        /*do something*/
        this.bgColor = "#FF0000AA";
    });

    var page = sm("do_Page");
    //订阅当前页面的 loaded 事件( 页面加载完成时候触发,或通过fire方法手动触发.);
    page.on("loaded", function(){
        /*do something*/
        var data = this.getData()// this == page;
    });

    //订阅当前页面的 xxxxx 事件( 只能通过 fire 触发 );
    page.on("xxxxx", function(data){
        /*do something*/
    });

    //其他详见各组件的API.

  • 触发已订阅的事件[ .fire() ] :如果是组件支持的事件, 组件会根据自身当前状态自动触发(Button:touch / Page:loaded ...).如果不是组件所支持的事件, 需要调用 fire 方法手动触发.
    button.fire("touch");
    button.fire("touch001", { demo : "手动触发touch001"});
    page.fire("xxxxx", { demo : 1, demo2 : false , demo3: "xx?xx"});

    //fire方法传递两个参数,第一个参数是事件名称, 第二个参数是需要传递的数据(此参数可忽略).
    //事件响应时,第二个参数的值,会传递到订阅时( on方法 )的回调函数的第一个参数上.更多说明参考事件机制相关文档

  • 注销已经订阅的事件[ .off() ] :调用 off方法即可
    button.off("touch");
    page.off("xxxxx");

5. require函数

  • js版本中的require:js中的require函数的实现参照了CommonJS的风格,但是并不是完全的CommonJS Modules 的实现.
    这里的详细用户可以参考文档
    /******** source/script/demo.js************************************/
    exports.add0 = function(a, b, c) {
        return a + b + c || 0;
    }

    module.exports.add1 = function() {
        var sum = 0, i = 0, args = arguments, l = args.length;
        while (i < l)  {
            sum += args[i++];
        }
        return sum;
    };
    //导出了两个函数 add0 和 add1
   /******* source/view/index.ui.js ************************************/
    var demo = require("demo");
    var t0 = demo.add0(1,2,3);
    var t1 = demo.add1(1,2,3,4,5,6);
    //require中的参数,就是对应的script目录下的文件名(不加.js);

回到顶部

你可能感兴趣的:(AppWorker教程-基础-组件概述)