extjs使用、总结、感悟

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zbraccp/article/details/53582498

提到ExtJs,笔者可以说是感触颇深,本人经历了Extjs许多个版本,大版本从2.0开始,我第一次关注它!之后再项目中用到了3.0,4.2,6.0等不同版本,可以说见证了Extjs的发展贺强大之处。
简单解释下什么是Extjs。它是一个高度分装的前端开发语言:javascript。高度分装:是指封装了几乎所有项目上都会用的前端组件,而不是不可拆解的。扩展性相当高,是我见到过最强大的前端框架。之前还用过easyui框架,bootstrap响应式框架,经历了多个项目后,发现Extjs框架还是比较靠谱的,尤其对于一个后台程序员来说,简直就是福音,再不用为了布局而头疼,再不用为了兼容性而烦恼,再不用写大堆的CSS。

下面介绍下Extjs的优缺点
事物都有两面性,有好就有坏。Extjs也是这样。
缺点
1:UI,在外观方面,Extjs无疑完败给bootstrap、jqueryUI,在样式和布局方面Extjs显得十分的生硬。
这里写图片描述
图上是我做的demo。树形结构,表格,左右布局。
2:Extjs依赖文件过于庞大,压缩后的“ext-all.js”,2M多,此外还有CSS样式文件等。这个问题直接导致很多互联网企业放弃Extjs,在高并发时代,大家都是在最求响应速度,加载过慢无疑使得用户体验很差。所以,Extjs不会出现在门户网站上,出现最多的地方是什么的?没错,企业级办公OA。Extjs的几套样式也是非常专业的OA风格。

优点
其实在上面的介绍中已经提到了很多Extjs的优点,比如说,组件多,实用与各种办公软件,比如说扩展性高,再比如说布局简单,不懂美工的也能做出大气的页面。更多的不说了,有兴趣的研究下Extjs,更值得提的是它的设计模式,读过源码的人一定能感觉出–其乐无穷啊。

废话不说,学习Extjs开始。
很多人说,我是写后台的,页面交给写前端的人去搞吧。而我想说,一个优秀的资深java高手,同样也能写一手好的前端代码。知识学到了就是自己的。
Extjs版本的选择:
1:如果你正在搭建自己公司的办公OA,推荐使用4.X版本,稳定版本。
2:如果之前没有接触过Extjs,单纯的想学习,推荐研究下4.2。
3:如果之前已经了解过Extjs,那么推荐学习最新的版本,目前官网已经发布6.X。
两个大的版本,4.0之后,Extjs提出前端代码规范:MVC设计模式,此MVC非彼MVC,后java设计模式的MVC有一定的区别。
无论是前端代码还是后台代码,都需要逻辑处理。而前端的工作会多一点,没有后台的数据访问,但是多了界面的交互,数据展示等。

Extjs中MVC的诠释:
M:对应java中的实体类(javaBean),Ext需要对后台返回的数据进行二次分装,也是OOP的表现。(代码如下:)

Ext.define("sys.user.model.UserModel", {
    extend:"Ext.base.model.BaseModel",
    fields: [
        {name:"CREATE_TIME",type:"date",dateFormat:"Y-m-d H:i:s"},
        {name:"UPDATE_TIME",type:"date",dateFormat:"Y-m-d H:i:s"},
        {name:"CREATE_USER",type:"string"},
        {name:"CREATE_USER_NAME",type:"string"},
        {name:"ACTIVE",type:"int"},
        {name:"USER_NAME",type:"string"},
        {name:"SEX"},
        {name:"LOGIN_NAME",type:"string"},
        {name:"PASSWORD",type:"string"},
        {name:"EMAIL",type:"string"},
        {name:"PHONE",type:"string"},
        {name:"IP",type:"string"},
        {name:"LAST_TIME",type:"date",dateFormat:"Y-m-d H:i:s"}
    ]
});

Ext.define:定义一个类,java中使用new关键字。
extend:继承,既然Extjs也模仿java的OOP,那么继承一定要有的,后面还会提到构造。
fields:定义一个类里面的属性集合。

V:视图表现层。java中V代表整个钱前段代码,包括:html、jsp、js、css等。而Extjs中,V表示构建页面的代码,没有逻辑处理、交互的代码。

 Ext.define("sys.user.view.UserView",{
    alias:"widget.UserView",
    extend:"Ext.base.view.BaseGridView",
    constructor:function(){
        this.selModel=null;
        this.forceFit=false;
        this.searchFiledName="员工姓名/登录帐号/联系方式/邮箱";
        this.columns=[
            {header:"员工姓名",dataIndex:"USER_NAME"},
            {header:"性别",dataIndex:"SEX"},
            {header:"登录帐号",dataIndex:"LOGIN_NAME"},
            {header:"创建人",dataIndex:"CREATE_USER_NAME"},
            {header:"创建时间",dataIndex:"CREATE_TIME"},
            {header:"最后修改时间",dataIndex:"UPDATE_TIME"},
            {header:"邮箱",dataIndex:"EMAIL"},
            {header:"联系方式",dataIndex:"PHONE"},
            {header:"状态",dataIndex:"ACTIVE"},
            {header:"上次登录IP",dataIndex:"IP"},
            {header:"上次登录时间",dataIndex:"LAST_TIME"}
        ];
        this.tbar=[//初始化工具栏
            "->",
            {text:"新增",action:"add",iconCls:"Add"},
            {text:"删除",action:"delete",iconCls:"Delete"},
            {text:"编辑",action:"edit",iconCls:"Edit"},
            {text:"查看岗位",action:"searchpost",iconCls:"Edit"},
            {text:"导出",action:"export",iconCls:"ExportExcel"},
            {text:"筛选",action:"search",iconCls:"Search"}
        ];
        this.putStore("sys.user.store.UserListStore");
        this.callParent(arguments);
    }
});

alias:为类定义别名。
constructor:构造函数,构造函数的作用不解释了,和java一样。
this.callParent(arguments):调用父类构造函数,Extjs中规定:在继承关系中,子类有构造函数,不会自动调用父类构造函数,如果需要执行父类构造函数,需要手动调用。
C:也是Extjs的核心,逻辑处理、交互。

Ext.define("sys.user.controller.UserController",{
    extend:"Ext.base.controller.BaseController",
    models:["Ext.base.model.BaseModel"],
    editUrl:window.ROOT+"/sys/user/edituser",//编辑用户
    init:function()
    {
        var me=this;
        var grid;
        var winForm=null;
        var postWin=null;
        var searchPostWin=null;
        this.control({
            "UserView":{
                afterrender:function(gp){
                    grid=gp;
                    winForm=null;
                    postWin=null;
                    grid.down("button[action=add]").on("click",addUser);
                    grid.down("button[action=delete]").on("click",deleteUser);
                    grid.down("button[action=edit]").on("click",updateUser);
                }
            }
        });
        /**
         * 修改用户
         */
        function updateUser(){
            var rows=grid.baseIsSelected();
            if(rows){
                if(winForm==null)
                {
                    winForm=Ext.create("sys.user.view.UserFormView");
                    winForm.down("button[action=save]").on("click",editUser);
                }
                var form=winForm.down("form");
                form.reset();
                winForm.setTitle("修改信息");
                form.down("hidden[name=OPER]").setValue("edit");
                form.getForm().loadRecord(rows[0]);
                winForm.show();
            }
        }
        /**
         * 添加用户
         */
        function addUser(){
            if(winForm==null)
            {
                winForm=Ext.create("sys.user.view.UserFormView");
                winForm.down("button[action=save]").on("click",editUser);
            }
            winForm.down("form").reset();
            winForm.setTitle("添加信息");
            winForm.down("hidden[name=OPER]").setValue("add");
            winForm.show();
        }
        /**
         * 删除用户
         */
        function deleteUser(){
            grid.baseDeleteRow(me.editUrl);
        }
    },
    /**
     * push to panel
     * @return {}
     */
    show:function(){
        return Ext.create("sys.user.view.UserView");
    }
});

init:初始化函数。
this.control:控制器控制核心。

MVC有了,那么数据怎么访问呢,怎么请求后台呢?

补充一个Store,类似java中的数据访问层Dao

扫描二维码关注公众号,回复: 4096052 查看本文章
Ext.define("sys.user.store.UserListStore",{
    extend:"Ext.base.store.BaseGridStore",
    proxy:{type:"ajax",url:window.ROOT+"/sys/user/getuserlist",reader:{rootProperty:"data",totalProperty:"result"}},
    model:"sys.user.model.UserModel"
});

目录结构如下:
这里写图片描述
这样一来,前端的代码也被我们用MVC的模式分离出来了。为什么这么设计呢?本来一个js就搞定的事情,为什么要分好几个呢?我在刚接触Extjs4.2的时候也很困惑。后来在项目中体会到了它的好处,当前端的交互很多的时候,交互很复杂的时候,有了这样的分层,代码维护起来轻松多了。

上面写的这些,只是对Extjs简单的认识,网上还有很多更详细的教程,这里不在罗说。
笔者是个写后台的程序员,在平时的学习中,少不了自己研究写新鲜东西,有了后台代码,就要有前端来展示,笔者又是个强迫症受害者,不好看的界面绝对不用,CSS功底不足,于是乎我和Extjs相识了。
笔者平时喜欢封装一些公共类来满足项目中的使用,让别人调用自己的代码,那感觉。。。。。。程序员们都懂!所以老毛病又犯了,Extjs中我也进行了二次封装,把一些常用的组件分装起来,下面会附上代码。
上面的代码中大家可能看到了有些其实就是我已经分装过的,比如:

extend:"Ext.base.model.BaseModel",//BaseModel就是分装的一个“类”
this.putStore("sys.user.store.UserListStore");//putStore就是分装的函数

二次分装的好处:假如有一天Extjs升级了,7.0,8.0,10.0,那么我们之前的项目想升级怎么办,如果过于依赖Extjs原有的封装,那么我们就太被动了,升级一次,大改一次。但是我们对Extjs的常用功能进行二次封装,用我们自己的函数实现Extjs的函数,那么升级就变得简单了,我们在升级的时候只需要升级二次封装的代码就OK了。

下面的目录结构是笔者亲自封装的:
这里写图片描述

业务中的Controller都继承BaseControlle,Model继承BaseModel,Store继承对应的Store,View继承对应的View。

下面是我对GridPanel的简单分装:

Ext.define("Ext.base.view.BaseGridView",{
    alias:"widget.BaseGridView",
    extend:"Ext.grid.Panel",
    singleton:false,//指定为true类定义单例类(该类只能有一个实例)
    region:"center",
    columnLines:true,
    forceFit:true,
    border:false,
    page:true,
    searchFiled:true,
    selModel:{selType:"checkboxmodel"},//复选框
    viewConfig:{
        markDirty:false,
        enableTextSelection:true
    },
    columns:[],
    putStore:function(s){//自定义函数
        var st=Ext.create(s,{proxy:{extraParams:{"p":this.page}}});
        this.store=st;
        if(this.searchFiled){//搜索文本框
            if(!this.searchFiledName){
                searchFiledName="";
            }
            if(!this.tbar){
                this.tbar=[];
            }
            var txSearchField=Ext.create("Ext.plug.form.SearchField",{width:300,emptyText:this.searchFiledName,labelWidth:0,store:st});
            this.tbar.unshift(txSearchField);
        }
        if(this.page){
            this.bbar=[{xtype:"pagingtoolbar",store:st,displayInfo:true}];
        }
        for(var i=0;i<this.columns.length;i++){
            if(!this.columns[i]["align"])this.columns[i]["align"]="center";
            if(!this.columns[i]["width"])this.columns[i]["width"]=150;
        }
    },
    /**
     * 获取选中行
     */
    baseIsSelected:function(){//自定义函数
        var list=this.getSelectionModel().getSelection();//Extjs的函数
        if(list.length>0){
            return list;
        }
        else {
            return false;
        }
    },
    /**
     * 数据刷新
     */
    baseReloadData:function(){//自定义函数
        this.getStore().loadPage(1);//Extjs的函数
    }
});

学习Extjs的过程中,我在这里总结下:
阶段1:读懂一个demo代码,理解设计模式和编程是想。
阶段2:理解事件、函数,绑定事件、触发函数。(afterrender,beforeload等)这些经常用的关键词要深刻体会。
阶段3:本章介绍的Extjs不是很多,因为笔者希望和大家分享编程思想,而不是Extjs的技术点。技术点有很多博客都已经写的很详细了,官网也有API。在Spring中经常会提到AOP,笔者也是受AOP思想的启发,在程序员之路上,慢慢摸索着。

猜你喜欢

转载自blog.csdn.net/zbraccp/article/details/53582498