extjs4知识点汇总

原创
2013/08/20 16:41
阅读数 3.4K

1.Config Options 和Public Properties区别:

     配置项是在创建组件时生成,相当于构造函数的参数;属性是在组件创建后能取到的组件属性,相当于成员变量

2.初始化执行过程

controller的init方法优先于application的launch方法执行,而Ext.onReady方法是在页面加载完DOM后执行,延迟加载(不需要加载图片 ) 

3.extjs的事件机制

    Ext.util.Observable.js是extjs的自定义事件 和Ext.EventMangement.js解决浏览器对事件兼容问题,和对原始事件的封装

4.注意extjs事件中的两个重要属性参数(scope和single)

extjs利用on方法绑定事件时,参数scope默认是触发该事件的对象this,实际开发中,可以将这个scope复写为其他任意组件single默认为false,比如渲染renderer这类事件,只需要渲染一次,可以将事件定义为只触发一次,节约内存资源。

myGridPanel.on('hide',this.handlerClick,this,{
    single:true,
    delay:100
})
on方法参数分别为eventName,fn,scope,options(scope:'',delay:'',single:'',buffer:'',target:'',element:'')

另外,Events中有些事件参数有Ext.EventObject,可以使用e.getTarget获得触发事件的组件

5.在创建自定义类时,先构造(constructor)后初始化(initComponent)。如:

         

 Ext.define('Btn',{
          extend:'Ext.button.Button',
          initComponent:function(){
              alert('后初始化部件启动...');
          },
          constructor:function(){
              this.text = new Date();
              this.renderTo = Ext.getBody();             
              this.callParent();
              alert('先构造函数启动...');
          }
      });

      Ext.onReady(function(){
          Ext.create('Btn');
      });

6-1.extjs的store中的proxy可以配置多个url(增删改)

proxy:{
  type:'ajax',
  api:{
    read:'url1',
    update:'url2'
    create:'url3',
    Destory:'url4'
  }
  reader:{
    root:'',
    url:'',
    successProperty:'success'
  }

}

6-2.更新数据记录

this.getStore().sync()

7.Ext.data.Model是Ext.data.Record的升级版

8.extjs滚动条问题

在grid的columns里面配置数据变量,配置autoScrll:true,scroll:true后不会出现滚动条,但是写死又可以,不知道什么情况

可以控制具体是x方向还是y方向有滚动条overflowX:'auto'或者overflowX:'auto'

9.FormPanel的提交\加载

注意:后台传过来的json格式,如{success:ture,data:{xx:xxx,……}},与grid不同

myFormPanel.getForm().submit({//提交
  //clientValidation: true,
    url: 'xxx.action',
    params: {
        newStatus: 'delivered'
    },
    success: function(form, action) {
       Ext.Msg.alert('Success', action.result.msg);
    },
    failure: function(form, action) {
       Ext.Msg.alert('Failure', action.result.msg);
    },
})

myFormPanel.getForm().load({//加载
    url: 'xxx.action',
    params: {
        consignmentRef: myConsignmentRef
    },
    failure: function(form, action) {
        Ext.Msg.alert("Load failed", action.result.errorMessage);
    }
});

10.gridPanel的提交、加载

注意:后台传过来的json格式,如{total:12,rows:[{xx:xxx,……},{}]},与form不同

myGridPanel.store.load({
    params:{params:xx}
});

默认参数提交,即每次请求都会提交的参数

myGridPanel.store.proxy.extraParams={xxx:xx}

11.Ajax请求提交

Ext.Ajax.request({
    url: 'xxx.action',
    params: {
        id: 1
    },
    success: function(response){
        var text = response.responseText;
        // Ext.JSON.decode(text)
    }
});

12.disable与readOnly区别

有时候form表单中不想用户编辑。disable:true,视图变灰,而且提交没有此域;而readOnly可以提交 

13.动态构建gridPanel

有时候需求为:gridPanel的列不固定,需要动态实现,则可以采用如下方法

     创建一个空gridPanel,store:null,columns:[]

     通过ajax请求获取columns,并构建相应的store

     myGridPanel.reconfigure(store,columns) 

14.Extjs选择器

根据id找组件:Ext.getCmp('id')

某组件上面的组件 MyCom.up('form');某组件下面的组件MyCom.down('form');

某组件的父和兄弟:MyCom.ownerCt;MyCom.nextSibling();MyCom.previousSibling();

15.grid的多选配置项

//checkbox放在最后一栏需要配置:injectCheckbox : Number/String

selModel : Ext.create('Ext.selection.CheckboxRowModel',{injectCheckbox : 'last'}),

multiSelect:'MULTI'

16.extjs触发事件函数

extjs4大型项目一般采用MVC模式,事件触发写在controller(详情见API中Ext.app.Controller),根据别名作为选择器如:

Ext.define('MyApp.controller.Users', {
    extend: 'Ext.app.Controller',
    models:[],
    stores:[],
    views:['myaliasname'],

    init: function() {
        this.control({
            'myaliasname': {
                render: this.onPanelRendered
            }
        });
    },

    onPanelRendered: function() {
        console.log('The panel was rendered');
    }
});

一些比较简单的事件,可以使用listeners属性完成 ,如:

listeners: {
        click: {
            element: 'el',
            fn: function(){ console.log('click el'); }
        },
        dblclick: {
            element: 'body', 
            fn: function(){ console.log('dblclick body'); }
        }
    }

或者handler属性,一般是按钮,combobox等组件,和listeners类似

17.extjs中config中配置对象的属性可以使用get方法获取

Ext.define('SmartPhone', {
     config: {
         hasTouchScreen: false,
         operatingSystem: 'Other',
         price: 500
     },

     isExpensive: false,

     constructor: function(config) {
         this.initConfig(config);
     },

     applyPrice: function(price) {
         this.isExpensive = (price > 500);

         return price;
     },

     applyOperatingSystem: function(operatingSystem) {
         if (!(/^(iOS|Android|BlackBerry)$/i).test(operatingSystem)) {
             return 'Other';
         }

         return operatingSystem;
     }
});

var iPhone = new SmartPhone({
     hasTouchScreen: true,
     operatingSystem: 'iOS'
});

iPhone.getPrice(); // 500;
iPhone.getOperatingSystem(); // 'iOS'
iPhone.getHasTouchScreen(); // true;
iPhone.hasTouchScreen(); // true

iPhone.isExpensive; // false;
iPhone.setPrice(600);
iPhone.getPrice(); // 600
iPhone.isExpensive; // true;

iPhone.setOperatingSystem('AlienOS');
iPhone.getOperatingSystem(); // 'Other'

18.extjs对象中配置static中的方法为静态方法:

Ext.define('Computer', {
     statics: {
         factory: function(brand) {
            // 'this' in static methods refer to the class itself
             return new this(brand);
         }
     },

     constructor: function() { ... }
});

var dellComputer = Computer.factory('Dell');

18.extjs动态添加和删除容器内的组件

添加:

方法一:在父组件容器里面配置空items,即items:[],—>创建的子组件—>像操作数组一样push到父容器内,父容器.push(子容器)—>父容器重新渲染一次,父组件.doLayout()

方法二:创建的子组件—>调用父容器的add方法,父容器.add(子组件)

删除:

1.针对添加方法一的删除:

将items内的子组件删除:var destroyItem = 父容器.items.items.pop()—>destroyItem.destroy()

2.针对添加方法二的删除:

直接调用父容器的remove方法:父容器.remove(子组件),子组件内可以配置itemId则父容器.remove(‘itemId’)

19.extjs中json的处理

1.将json格式的字符串转换为json对象

Ext.JSON.decode(string)

JSON.parse(string)

eval("("+string+")");//注意eval里面有括号

2.将json对象转换为json格式的字符串

Ext.JSON.encode(json)

JSON.stringify(json)

20.extjs store加载后callback函数的使用

store.load({ 
     scope: this, 
     callback: function(records, operation, success) {
//  数据加载后后继操作
         console.log(records); 
     }
});

21.在调试extjs时,注意事项

     注意console.log()和alert()的区别,console.log()显示的为打印的最终结果,类似异步执行;alert停在当前,后面的语句不会执行。如果需要等待(延迟渲染、ajax异步请求),可以使用setTimeout(function(){},1000),在function里面写好需要执行的语句

22.extjs组件释放,内存泄漏问题

     组件创建后未销毁,一般这些组件继承Ext.Component,它在创建时会注册到Ext.ComponentMgr中(所以在检查组件销毁,可以执行Ext.ComponentMgr.getCount()或ComponentMgr.each(function(key,value,length){console.log(key)})查看组件),不调用destroy方法是不会从中移除的,所以它永远不会被释放。一般调用removeAll方法(abstractContainer子类,比如panel)可以实现级联销毁。也可以在initComponent,destroy事件中递归执行destroy()方法。对于组件销毁了查看store的销毁情况,Ext.data.StoreManager.getCount或each。默认store的配置autoDestroy为ture,extjs4后改为私有方法。默认组件销毁,store也跟着销毁了如果store里面配置了storeId,store实例会在storeManager中保留,需要手动销毁!Ext.data.AbstractStore的源码:

destroyStore: function() {
    var me = this;
    if (!me.isDestroyed) {
        if (me.storeId) {
            Ext.data.StoreManager.unregister(me);
        }
        me.clearData();
        me.data = me.tree = me.sorters = me.filters = me.groupers = null;
        if (me.reader) {
            me.reader.destroyReader();
        }
        me.proxy = me.reader = me.writer = null;
        me.clearListeners();
        me.isDestroyed = true;

        if (me.implicitModel) {
            Ext.destroy(me.model);
        } else {
            me.model = null;
        }
    }
}


23.采用事件冒泡机制,避免每个子组件绑定事件,提高性能

      extjs的委托应该是事件冒泡的演变(不确定),一个委托模式的示例是工具条有10个按钮,而你希望在用户将鼠标移动到按钮上面时,为每个按钮委派一个Ext.Tooltip,而且每个Ext.Tooltip都显示不同的文本。如果你创建10个Ext.Tooltip并委派给10个按钮,那么它不是一个优化的解决方案。你只需要创建一个Ext.Tooltip并委派给10个按钮的父元素,也就是工具条。当用户将鼠标移动到工具条上方时,你可以显示相同的Ext.Tooltip,但其文本可根据目标元素(实际上就是按钮)而显示不同的文本(越多getTarget方法可了解如何获取目标元素)。使用这个技术,只需要创建1个Ext.Tooltip,而且只需要在工具条绑定一个监听事件。这可节省内存使用,而且在你的应用运行时实现了相同的效果。找到示例中Ext.Tooltip的delegate属性信息

24.xtype和new、Ext.create区别

new,Ext.create方法先将class加载到内存,渲染时直接使用。会引起两个方面的问题。1.在渲染时访问其他组件可能引起null,因为其他组件不一定已经渲染。2.new和create方式容易导致内存泄漏。xtype实现了组件懒初始化,xtype先标识是哪个class,渲染时才将class加载到内存。new引起的内存泄漏的例子:

如 tbar = [new TextField({...})],tbar所在的Grid作为TabItem,并且该TabItem延迟渲染,那么由于new TextField({...})已经注册,但因为未渲染,toolbar中未添加该Field为其Item,导致未销毁组件。(解决办法:通过复写onDestroy主动销毁,或是使用{xtype:""}延迟组件创建),总之,如果主动new ...的组件,那么注意销毁时,是否销毁了相应的组件

xtype的含义

25.内存泄漏注意事项

1、减少组件的嵌套

2、尽可能延迟HTMLElement的创建

DOM操作(读/写)的开销一向是昂贵的,尤其在IE6,读取DOM总会引起回滚。因此,经验法则是:尽可能延迟HTMLElement的创建 。以下是实现方式:

●组件Lazy初始化,这在xtype里可实现。

●尝试在渲染后(afterrender)后再执行昂贵的操作。

●避免在组件的构造函数或initComponent方法中对其它组件进行不必要的实例化或渲染。

泄漏分类与解决思路

26.注意combo的change事件

     在combo的change事件中获取兄弟节点引起找不到兄弟节点。以为combo在渲染之后值就已经改变了,则执行change事件。而此时兄弟节点不一定渲染完毕。解决办法:在change事件前面判断value是否为空,是则return。

27.动态改变树节点的文字

  先获取需要改变的节点(如itemclick事件,treePanel.getSelectionModel().getSeslection()获取target),获取的节点应该是Ext.data.Store.ImplicitModel(继承自Ext.data.Record也就是Ext.data.model),使用set('text','修改后需要显示的文字')方法,但是此时数据是dirty的,需要再次调用Model的commit方法

28.store去重

       虽然在store的model中配置idProperty作为“主键”去重,但是类似在多个combobox引用同一个store的场景下会造成重复项问题。

 var store = Ext.create('Ext.data.Store', {
        listeners: { load: function (store,records,successful) {
            vat me = store;
            var k, repeat = [], state = {};
            me.each(function (r) {
                k = r.get('需要去重复的键名称');
                if (state[k]) repeat.push(r);
                else state[k] = true;
            });
            me.remove(repeat);
        } 
        }
    });

笔记:


未完待续。。。


展开阅读全文
加载中

作者的其它热门文章

打赏
1
7 收藏
分享
打赏
2 评论
7 收藏
1
分享
返回顶部
顶部