Sencha Touch开发一些需要注意的地方

Sencha Touch开发一些需要注意的地方
  • 发表于 2年前
  • 阅读 4189
  • 收藏 2
  • 点赞 0
  • 评论 0

Sencha Touch开发一些需要注意的问题

如今Sencha Touch已经升级到2.4了,功能更加强大,性能也有所提升。
但由于一些功能的改进,文档并没有及时更新,导致开发时会遇到一些困难。
结合我使用的经验总结一些需要注意的地方,希望能帮助大家。

-------------------
Sencha Touch的开发流程

下载SDK,安装Sencha Cmd。

创建项目:

sencha generate app MyApp ../test
打包项目(压缩,便于部署)
sencha app build
由cmd生成的项目会自动加载类库文件,文件太多,导致等待时间过长,
可以直接引入resources/css/sencha.css和sencha_touch_all.js来提高速度,
但打包时需要还原,否则会出错

根目录下的app.js是程序的入口文件,代码如下所示:
Ext.application({
    name: 'MyApp', //The name is used to create a single global namespace for your entire app

    requires: [
        'Ext.MessageBox',
        'Ext.navigation.View',
        'Ext.dataview.List',
        'Ext.plugin.PullRefresh',
        'Ext.plugin.ListPaging'
    ],

    controllers:[
        'Main'
    ],

    views: [
        'Main',
        'ArticleList'
    ],

    models:[
        'MyApp.model.Article'
    ],

    stores:[
        'MyApp.store.Articles'
    ],

    icon: {
        '57': 'resources/icons/Icon.png',
        '72': 'resources/icons/Icon~ipad.png',
        '114': 'resources/icons/Icon@2x.png',
        '144': 'resources/icons/Icon~ipad@2x.png'
    },

    isIconPrecomposed: true,

    startupImage: {
        '320x460': 'resources/startup/320x460.jpg',
        '640x920': 'resources/startup/640x920.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    launch: function() {
        // Destroy the #appLoadingIndicator element
        Ext.fly('appLoadingIndicator').destroy();

        // Initialize the main view
        Ext.Viewport.add(Ext.create('MyApp.view.Main'));
    },

    onUpdated: function() {
        Ext.Msg.confirm(
            "Application Update",
            "This application has just successfully been updated to the latest version. Reload now?",
            function(buttonId) {
                if (buttonId === 'yes') {
                    window.location.reload();
                }
            }
        );
    }
});

用到的组件都需要在requires中引入,否则JS调试器中会有警告,
Sencha Touch采用MVC结构,所有controller、model、store、view文件需要在这里引入.
实际文件存放在app文件夹下的相应目录
-------------------------------------
自定义组件除了extend属性,其他属性需要写在config下:
Ext.define("MyApp.model.Article", {
    extend: "Ext.data.Model",
    config: {
        fields: [
            {name: "title", type: "string"},
            {name: "content",  type: "string"},
            {name: "add_time", type: "string"}
        ]
    }
});

Ext.define('MyApp.store.Articles',{
    extend:'Ext.data.Store',
    config:{
        model: "MyApp.model.Article",
        proxy: {
            type: "ajax",
            url : listUrl,
            reader: {
                type: "json",
                rootProperty: "root"
            }
        },
        autoLoad: true,
        pageSize:10,
        listeners:{
            'beforeload':function(store){
                //console.log('start');
                if(store.getAllCount()==0){
                    showMask();
                }
            },
            'load':function(){
                hideMask();
            }
        }
    }
});
----------------------------------
card布局可以配置页面的切换动画
Ext.create('Ext.Panel',{
layout:{
    type:'card',
    animation:'fade'
},
items:[
    {
    .....
    },
    {
    .....
    }
 ]
});

----------------------------------

Ext.dom.Element,同Ext.Element,是Sencha Touch封装的dom对象,
是对普通dom的进一步封装,给dom对象添加了一些新方法
// 根据id获取元素,返回Ext.Element类型
var el = Ext.get("my-div");
// 根据HTMLElement获取元素,返回Ext.Element类型
var el = Ext.get(myDivElement);

//HTMLElement是普通的dom对象

//Ext.Element 获取所有img 返回数组(HTMLElement)
el.query('img');

//Ext.Element 获取第一个img 返回单个对象(HTMLElement)
el.down('img',true);

//返回单个对象(Ext.dom.Element)
el.down('img');

//Ext.dom.Element修改样式
el.applyStyles({
    color:'red'
});

//普通HTMLElement修改样式
el.style.width = '100%';

-----------------------------------
//创建loading
Ext.Viewport.setMasked({
    xtype:'loadmask',
    message:'请稍后...'
});

//关闭loading 为什么不是unMask?很奇怪
Ext.Viewport.unmask();

//也可以使用
Ext.Viewport.setMasked(false);
-----------------------------------
文档中方法带绿色右箭头表示CHAINABLE,支持类似jQuery的链式语法
------------------------
painted事件
Fires whenever this Element actually becomes visible (painted) on the screen
该事件发生在dom加载完成时
----------------------------------
在使用布局时,一定要注意,如果父元素不配置layout属性(默认将为auto布局)
子元素一定要有高度,否则可能不会显示出来,即高度为0

card布局示例:
var panel = Ext.create('Ext.Panel', {
    layout: 'card',
    items: [
        {
            html: "First Item"
        },
        {
            html: "Second Item"
        },
        {
            html: "Third Item"
        },
        {
            html: "Fourth Item"
        }
    ]
});

panel.setActiveItem(1);

每种布局方式都支持docked(停靠)属性:
灵活使用docked属性,可以很方便创建复杂的布局
Ext.create('Ext.Container', {
    fullscreen: true,
    layout: 'hbox',
    items: [
        {
            docked: 'top', //可以是top bottom right left
            xtype: 'panel',
            height: 20,
            html: 'This is docked to the top'
        },
        {
            xtype: 'panel',
            html: 'message list',
            flex: 1
        },
        {
            xtype: 'panel',
            html: 'message preview',
            flex: 2
        }
    ]
});

pack和align是布局的两个辅助定义项,pack代表了当前布局维度的特性,align则相反
例如对hbox布局,pack的定义表示水平方向的特性,而align表示垂直方向的特性:

layout: {
    type: 'hbox',
    align: 'start', //垂直方向停靠起始位置
    pack: 'start' //水平方向停靠起始方向,效果等同左对齐
},

align和pack可能的值:
start   
center 居中对齐
end
justify 两端对齐(自适应父元素的宽度或高度)

可以理解为word排版中的四种对齐方式:
左对齐
右对齐
居中对齐
两端对齐 

获取容器的布局
var layout = container.getLayout();
-----------------------------------------

对于滚动属性的说明。
每个容器都可以通过配置scrollable:true来实现滚动,
但要注意,对于子元素有滚动的,父元素不能有滚动,否则可能会出现滚动条冲突的问题

-----------------------------

使用控制器可以是代码变得干净和可读性强,下面的例子展示了controller的使用:

Ext.define('MyApp.controller.Sessions', {
    extend: 'Ext.app.Controller',

    config: {
        refs: {
            loginForm: 'formpanel' //组件查询 使用xtype 
        },
        control: {
            'formpanel button': { //也可以使用类似于css选择器的查询方式
                tap: 'doLogin' //该方法在下面定义
            }
        }
    },

    doLogin: function() {
        var form   = this.getLoginForm(), //根据refs中的loginForm自动生成getLoginForm方法

            values = form.getValues();

        MyApp.authenticate(values);
    }
});

-----------------------------------

组件查询(ComponentQuery),使用组件查询可以像CSS选择器一样
获取应用中的组件,下面通过一些例子来展示这一强大功能。
//获取指定属性的panel
Ext.ComponentQuery.query('panel[cls=my-cls]')

//模糊查询
Ext.ComponentQuery.query('panel[cls~=my-cls]')
//匹配结果
Ext.create('My.Panel', {
    cls : 'foo-cls my-cls bar-cls'
});

//根据id查询
Ext.ComponentQuery.query('#myCt panel');

//查询孩子节点
var directChildPanel = Ext.ComponentQuery.query('#myCt > panel');

//查询多个组件
Ext.ComponentQuery.query('gridpanel, treepanel');

//获取禁用的元素
var disabledFields = myFormPanel.query("{isDisabled()}");

//值得注意的是,类似于isDisabled这样的方法还有一些,只要是返回布尔类型的,都可以作为
//查询参数,另外,query方法不只是可以用于Ext.ComponentQuery,对于每个容器组件都可以使用,上面的
//查询将会在myFormPanel的子元素中进行,而Ext.ComponentQuery.query的查询范围是全局
--------------------------------

//利用profile可以为不同的设备创建不同的界面,而共享相同的model和store
//现阶段我们不需要实现这样的功能,所以不做研究

//一些组件的初始化方法的执行顺序:
Controller#init functions called
Profile#launch function called
Application#launch function called
Controller#launch functions called
//可以利用该顺序来合理执行一些初始化逻辑
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值