框架笔记

框架笔记

基于Intel's App Framework

http://app-framework-software.intel.com/api.php

进新公司第四天了,第一二两天都在注册邮箱、域、gitLab、wiki、OA,装软件,熟悉IDE。

第三天终于用IDE做了一个静态的画面。

今天打算看js API并且运用到自己做的画面中去。

开始之前,先总结巩固。

只是一些操作,软件名用alias代替,应该不涉及版权问题。

第一天,入职,注册,装机。。

第二天,向IDE开发组的ld姐姐学习了IDE的操作方法:

1.创建一个新Project或者import一个已经存在的Project

  创建:(顶部工具栏上“反D“形的按钮一键生成)

  导入:  File/import/General/Existing Projects into Workspace

2.初始化画面用的js文件 app.js 在工程目录中的位置是:

  <projects_name>/src/web

其底部:

// We wait until app.ready is available to fetch the data, then we wire up the existing data in the templates
app.ready(function() {
    if(app.isStmDefined()) {
        try {
            StateRouter.start();
        } catch (e) {
            app.route("Main"); 
            console.log(e);
        }
    } else {
        app.route("feedly_01");
    }
});

启动默认本来是指向名为Main的画面,我将else中的route指向改为了feedly_01即我做的第一个画面。

这样运行的时候就从我做的画面启动了。

3.Winscape (画面)

  用IDE开发的页面不是一般网页那种一张一张的html,而是一个一个的winscape

  在winscape中的元素是相当于服务器环境中的状态,所以整个winscape只能用IDE的所见即所得功能或者设备simulator以及运行了虚拟服务器后在chrome浏览器中查看。

4.CC (Custom Control)

  分为两种:

    Automatic Custom Control (采用IDE的可视化编辑功能)

    Manual Custom Control(可以全部手写html,css,js)

当然我会选择后者。

在制作CC的时候先用IDE创建新的Manual CC,

然后在CC的html同级目录做一个叫做preview的html,其结构就是在CC的div外面套上html结构,在CC专有css之前引用几个工厂级的css,像一般网页一样进行布局。做成以后,import CC,并且选中Workbench中的CC元件,用鼠标右键中的IDE Tools/Release CC,这样CC就被释放到<projects_name>/src/web/resources/cc/下。

选中要放入CC的Winscape,在画面左侧会看到多了一个Resources CC,双击会看到下拉出刚才导入的CC,

把这个CC拖入Outline窗口内想要放入的容器中,该<CC的名称>将表现为对应的winscape的html中DOM节点中的data-role属性。

编辑winscape的html和css来调整cc的布局位置。

注意css的优先级,cc之间不要用同样的class名,会冲突。

用模拟器和chrome调试,修改的时候先在workbench改,改好释放,不要直接改resources下的cc,以免workbench中仍然存放旧版本。

5.FC (Function Control)

和CC一样是可以外部编写的程序控制模块,暂时ld姐姐能力有限还没有进一步讲解,以后进阶再说。

这样,第三天就这样完成了一个画面。

第四天,WebAPI的js解读:

该API目前有25个js文件。

首先知道itu是iAuto.ui.framework.App的缩写:

 8870 var itu = (function() {
 8871      var uif = iAuto.ui.framework, 
 8872         itu = {
 8873              app : uif.App, 
 8874              controller : uif.Controller, 
 ....
 8882              resource : uif.ResourceManager
 8883          };
 8884     return itu;
 8885  })();

 CC的js文件在IDE中生成的时候,就已经初始化了命名空间和结构,形如:

/**
 * Author: 
 */
itu.xcontrol.define("headbar", {
    
    views: ["headbar.html"],
    
    // The properties of the custom control.
    config: {
        
    },
    // The method would be called when create an instance.
    onCreate: function() {
        this.setView("headbar.html", {});
    },
    
    _createCmp_ : function() {
        // ####  #### // 
    },
    
    _bindEvent_ : function() {
        // ####  #### // 
        var me = this;
    }
});

CC的js基础:

他说我们采用的https://github.com/olado/doT 

另外有一些移动设备事件是用的https://github.com/hammerjs/hammer.js/wiki/Getting-Started

支持:

 1 hold
 2 tap
 3 doubletap
 4 drag, dragstart, dragend, dragup, dragdown, dragleft, dragright
 5 swipe, swipeup, swipedown, swipeleft, swiperight
 6 transform, transformstart, transformend
 7 rotate
 8 pinch, pinchin, pinchout
 9 touch
10 release
11 gesture

doT的文档慢慢看,

首先知道插值{{=it.title}}

{{if (it.innerContent == true){}}
<div class="headarrow"></div>
{{}else{}}
<div class="badge"></div>
{{}}}//这几个括号是一个整体,它是if语句的结束符,如果没有else的话就像这样:

{{if (it.innerContent == true){}}
<div class="headarrow"></div>
{{}}}

chj主要告诉我doT如何把CC的html文件静态插入到DOM树,以及如何像后台语言标签那样插入数据,但是这个数据是静态的,只载入一次。

上面我自己看到的CC配置用js,除了写js,同时还要配置xml

每次IDE生成xml的时候都会有一行sample property和一行sample event的样例注释

<!-- sample property
        <Property name="_prop_" type="String" default="" action="config"/> 
    -->
<!-- sample property
        <Event name="_eventname_"> 
            <Param name="_eventparam_" type="string" />
        </Event>
-->

照着样例的写法来配置name(CC在itu.xcontrol.define()中config对象中的若干属性),type(字符串,布尔。。),default(true或者false或者空着)

例如:

itu.xcontrol.define("titlebar", {

    views : [ "titlebar.html" ],

    // The properties of the custom control.
    config : {
        title : null,
        showLeftButton : false,
        showRightButton1 : false,
        showRightButton2 : false,
        showRightButton3 : false,
        leftButtonSrc: "",
        rightButtonSrc1: "",
        rightButtonSrc2: "",
        rightButtonSrc3: "",
    },
    // The method would be called when create an instance.
    onCreate : function() {
        var me = this;
        this.setView("titlebar.html", {
            showLeftButton : me.getShowLeftButton(),
            showRightButton1 : me.getShowRightButton1(),
            showRightButton2 : me.getShowRightButton2(),
            showRightButton3 : me.getShowRightButton3(),
            title : me.getTitle(),
            leftButtonSrc:me.getLeftButtonSrc(),
            rightButtonSrc1:me.getRightButtonSrc1(),
            rightButtonSrc2:me.getRightButtonSrc2(),
            rightButtonSrc3:me.getRightButtonSrc3()
        });
    },

    onShow : function() {
        this._customEvents();
    },
    
    onHide : function() {
        this._unbindEvents();
    },

    updataTitleBar : function(title) {
        var content = $("#tb-content-span");
        
        content.html(title);
    },
    
    refreshTitleBar : function() {
        var me = this,
            content = $("#tb-content-span");
        
        content.html(me.getTitle());
    },
    
    changeRightButton1 : function(src) {
        var r1 = $("#tb-rightbutton1"),
            img = "url("+src+")";
        
        r1.css("background-image", img);
    },
    
    changeRightButton2 : function(src) {
        var r2 = $("#tb-rightbutton2"),
            img = "url("+src+")";
        
        r2.css("background-image", img);
    },
    
    _bindEvents : function() {
        var me = this;
        var $el = me.$element;

        var $back = $el.find("#tb-leftbutton");
        itu.event.on($back, "tap", function(){$el.trigger("touchLeft");}, this);
        var $r1 = $el.find("#tb-rightbutton1");
        itu.event.on($r1, "tap", function(){$el.trigger("touchRight1");}, this);
        var $r2 = $el.find("#tb-rightbutton2");
        itu.event.on($r2, "tap", function(){$el.trigger("touchRight2");}, this);
        var $r3 = $el.find("#tb-rightbutton3");
        itu.event.on($r3, "tap", function(){$el.trigger("touchRight3");}, this);
    },
    
    _customEvents : function() {
        var me = this;
        var $el = me.$element;

        var $back = $el.find("#tb-leftbutton");
        itu.event.off($back, "tap");
        var $r1 = $el.find("#tb-rightbutton1");
        itu.event.off($r1, "tap");
        var $r2 = $el.find("#tb-rightbutton2");
        itu.event.off($r2, "tap");
        var $r3 = $el.find("#tb-rightbutton3");
        itu.event.off($r3, "tap");
    },

    _createCmp_ : function() {
        // #### 这个跟我无关,千万别跟它写重名的方法 #### //
    },

    _bindEvent_ : function() {
        // #### 这个跟我无关,千万别跟它写重名的方法 #### //
        var me = this;
    }
});
var me = this;
var $el = me.$element;

这里的$element指向IDE生成的DOM结构,就是带有IDE生成的id的用来包裹CC的容器。

另外还有一个$element不太用到,它是指向CC自身的html整个DOM结构。

先看一下CC的生命周期:

框架笔记

基本上我现在只要管onCreate()和onShow(),还有也许需要在onShow()和onHide()之间做一些切换。

onCreate()只是创建CC对象,onShow()会把CC加载到DOM树。

onHide()的时候可能要做一些处理。

而离开这个画面的时候,将依次执行onHide()、onDestroy()、onRemove()

所有的属性元件都可以用 .getPropertyname1()这样的形式获取到,只要加上get,然后首字母大写即可。

就像前面的:var me = this;

        this.setView("titlebar.html", {
            showLeftButton : me.getShowLeftButton(),
//此处的ShowLeftButton就是一个自定义的属性。

 另外如果要继承另一个CC的property和event,除了在js中要写extend:之外,

itu.xcontrol.define("CC_ButtonBase", {
    
    extend: 'CC_TouchEventBase',

    // The properties of the custom control.
    config: {

在xml头部的extends属性中也要写上

<Component extClass="titlebar" xtype="titlebar" label="titlebar" category="CustomControl" extends="iAuto.ui.Custom" isContainer="false" isCustomControl="true">

具体需要写的就是onShow()的部分了,

一般都会把要做的事情写成若干方法,首先必做的:

绑定事件(设好trigger供以后使用),

解绑事件(防止重复绑定事件导致的溢出),

其他DOM操作(这里要用到框架的语法,比如.css,.trigger,.find,.on,.off,.attr等等)

那么CC制作中js的部分就大致了解了,除了html和css还学会了写js和xml

另外跟chj还学了一招IDE的js format快捷键是ctrl+shif+f(windows)

剩下来winscape的js看上去和CC的也差不多,但是还没有讲解到。

多了一个initWinscapename: function(){} 应该属于惯用自定义方法名,毕竟不是.方法,显然自定义。

第五天,学会套CC那些属性和事件的半成品js和xml以后,我发现模拟器和run as app都预览不了乐,很正常,没数据嘛!

那么,和做ajax页面一样必须要静态假数据来测试!
静态数据写到哪里呢?这个没有规定,反正最初都是demo嘛,lbq哥哥过来讲解,怎么绑数据,怎么模拟各个画面的切换。

哥们发了一个他自己做的CC,其中有写数据的接口:

updateItems: function(items) {
        var tpl = itu.view.get("resources/cc/ddnlist/ddnlist.html"),
            html = tpl({
                items: items
            });
        this.$content = $.create(html);
        this.$element.empty().append(this.$content);
        //this.bindEvents(); 绑数据不必要包括这个,上面的全要
    },

另外我在学习的pocket项目的titlebar CC里面是这样写的:

updataTitleBar : function(title) {
        var content = $("#tb-content-span");
        
        content.html(title);
    },

就没有用tpl方法去绑数据了,只是用html方法写入。

上面的tpl方法只是把参数传入的items赋值给:左边的对象items,

这个items是要写入页面的整个数据模板,类似于json对象。

写到哪里去呢,虽然lbq说你随便写个地方吗,我觉得不靠谱,决定参照poket写在之前chj叫我不要去碰的_createCmp_里面:

_createCmp_ : function() {
        // #### Auto Code of Html5 Studio #### // 
        itu.xcontrol.create('AlertView', 'HomeView_alertview1', {});
        itu.xcontrol.create('favtoast', 'HomeView_favtoast1', {});
        itu.xcontrol.create('indicator', 'HomeView_indicator1', {});
        itu.fcontrol.start('ViewControllerStack');
        itu.fcontrol.start('DataProvider');
        itu.xcontrol.create('Menu', 'HomeView_menu1', {});
        itu.xcontrol.create('titlebar', 'HomeView_titlebar1', {
            title : "Pocket",
            showLeftButton : true,
            showRightButton1 : false,
            showRightButton2 : false,
            showRightButton3 : false,
            leftButtonSrc : "resources/img/menu.png",
            rightButtonSrc1 : "",
            rightButtonSrc2 : "",
            rightButtonSrc3 : ""
        });
        itu.xcontrol.create('List', 'HomeView_list1', {});
    },

像这样,itu.xcontrol.create的时候,就已经把“Pocket”和静态数据写进去了。

然后自己测试数据有没有绑好。

做好若干个画面以后,自己给按钮绑好事件后,用app.js中同样的写法,在事件中route不同的画面,自己调试。

第五天自己开始做写好doT的画面,假数据放在winscape创建时_createCmp_

第六七八(周一到周三)天继续做画面。

第九天,不幸迟到18秒。。和以前的师傅见面吃了午饭。。。帮sj调整了一下换了框架后的手机app样式。

第十天,将sj的两三百行样式精简到50来行,并对两个背景图片进行整合。

上面那种写假数据的方式,在第三周的第一个工作日(8/25)又被刷新了。

hyx带我联调了我做的contengcover画面,他告诉我CC的xml是不用写的,config也可以不用写。

但是通过实践发现,CC的property是必须在onCreate里面初始化好的。

绑定事件时不要直接绑到jqmobi的对象,最好用itu.event.on来绑到api的对象上。

还是采用tpl绑定数据,数据从winscape的js内执行CC的方法时传入。

首先要getCmp得到CC,然后执行CC的方法,带上参数(数据)。

另外还要注意一下this上下文,api里面有个方法,iAuto.uli.bind可以将他后面的第一个参数作为上下文赋给后面那个方法。比如iAuto.uli.bind(this,this.myfunc)

本来hyx用this.setMe(this)来储存this在var me内部,然后再用this.getMe()来取得原先的this,但是后来他发现用this来取this有自相矛盾,所以就放弃了这种方法。