ExtJS5搭建MVVM框架

概述

·  ExtJs5能够搭建Js的MVC框架,通过配置路由能够通过左边树形菜单导航到所需的页面,效果如下:

搭建JS框架

  新建home.htm页面作为ExtJs加载的主体页面,页面引入ExtJs需要的JS和ExtJs入口Js文件app.js

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>ExtJS演示</title>        
    <script type="text/javascript" src="Ext/ext-all.js"></script>    
    <script type="text/javascript" src="Ext/ext-locale-zh_CN.js"></script>
    <link rel="stylesheet" type="text/css" href="Ext/packages/ext-theme-crisp/build/resources/ext-theme-crisp-all_01.css">    
    <script type="text/javascript" src="app.js"></script>
</head>
<body>    
</body>
</html>

  app.js是ExtJs框架的入口,新建ExtJs中Application程序,指定所有新建ExtJs类的命名空间必须是MyApp开头,类似 MyApp.***,另外在app.js同级目录下新建app文件夹,里面新建文件夹view和viewmodel,这些文件夹的命名和规则必须是确定,不能任意修改,否则文件加载的时候,找不到相应的Js文件;

//ExtJs的入口,加载该Js之后,自动调用launch方法内容项
Ext.application({  
    name   : 'MyApp',
    extend:'MyApp.Application',
    autoCreateViewport:'MyApp.view.main.Main',
    // controllers:['Users'],
    listen: {
        controller: {
            '#': {
                unmatchedroute: 'onUnmatchedRoute'
            }
        }
    },
    onUnmatchedRoute: function(hash) {
        alert('Unmatched', hash);
    },
    init:function(){
      var me=this;
      me.setDefaultToken('all');
    },
    launch : function() {              
    }  
}); 

在app目录下,新建Application.js,命名MyApp.Application,代码如下,切记定义Js组件的名称,必须和文件路径对应

Ext.define('MyApp.Application',{
    extend:'Ext.app.Application',
    name:'MyApp',
    // stores:[
    //     'UserStore@MyApp.store'
    // ]
});

在app目录下,新建文件夹view\main,里面新建main.js,主要继承Ext.container.Container容器控件,负责页面布局使用,页面布局模式采用border使用,分为头部、导航、中间页面内容展示;

Ext.define('MyApp.view.main.Main',{
    extend:'Ext.container.Container',
    xtype:'app-main',
    requires:['MyApp.view.main.MainController','MyApp.view.main.Header','MyApp.view.main.Navigation','MyApp.view.main.ContentPanel'],
    controller:'main',
    layout:{type:'border'},
    items:[
    {region:'north',xtype:'app-header'},
    {region:'west',xtype:'app-navigation'},
    {region:'center',xtype:'app-contentPanel'} 
    ]
});

在app\view\main,新建总部内容MainController.js,类型是Ext.app.ViewController。内容如下,主要负责Main.js的Action和hander的绑定,控制页面的路由导航

var com={'message-view':'MyApp.view.message.MessageController','UserGrid':'MyApp.view.user.UserGridController'};
Ext.define('MyApp.view.main.MainController',{
    extend:'Ext.app.ViewController',
    requires:[
    'Ext.window.MessageBox'    
    ],
    alias:'controller.main',
    control:{
        'app-navigation':{
            selectionchange:'onTreeNavSelectionChange'
        }
    },
    onTreeNavSelectionChange:function(selModel,records)
    {
        var record=records[0];
        console.log(record.getId());
        if(record)
            this.redirectTo(record.getId());
    },
    routes: {
            ':id': {
                action: 'handleRout',
                before: 'beforeHandleRout'
            }            
        },
    handleRout: function (id) {
    console.log('Handle:'+id);    
        var me=this,
        mainView = me.getView(),  
        navigationTree = mainView.down('app-navigation'),  
        contentPanel = mainView.down('app-contentPanel'),  
        store=navigationTree.getStore(),
        node=store.getNodeById(id);
        contentPanel.removeAll(true),
        controlName=com[id];
        Ext.create(controlName);//MyApp.view.message.MessageController
        var module = Ext.apply({}, {
            xtype: id,
            itemId: id,
            //glyph: node.get('glyph'),
            title: node.get('text')
            //  tooltip: node.get('text')
        });
        contentPanel.add(module);
        var text = node.get('text'),  
        title = node.isLeaf() ? (node.parentNode.get('text') + ' - ' + text) : text;  
        contentPanel.setTitle(title);  
        //Ext.suspendLayouts(); //暂停布局
        Ext.resumeLayouts(true); //恢复布局
    },
    beforeHandleRout: function (id, action) {
    //动态实例化controller    
        action.stop();
        var me=this,
        store=Ext.StoreMgr.get('NavigationStore');
        node=store.getNodeById(id);
        if(node)
        {
          action.resume();  
        }
        else
        {
          Ext.Msg.alert(  
            '路由跳转失败',  
            '找不到id为' + id + ' 的组件. 界面将跳转到应用初始界面',  
            function() {  
                me.redirectTo('all');  
            }  
        );  
          action.stop();
        }
    },
});

 

在app\view\main,新建头部Header.js,内容如下

Ext.define('MyApp.view.main.Header',{
    extend:'Ext.Container',
    xtype:'app-header',
    height:52,
    layout:{type:'hbox',align:'middle'},
    items:[
        {xtype:'component',html:'<h2>XX系统</h2>'},
        {xtype:'component',html:'ExtJs实例',flex:1}
    ]
});

在app\view\main,新建导航Navigation.js,内容如下,PS 树形结构的id名称要和视图的xtype对应

Ext.define("MyApp.view.main.Navigation",{
    extend:'Ext.tree.Panel',
    xtype:'app-navigation',
    rootVisible:false,
    userArrows:true,
    // hideHeaders:true,
    width:250,
    minWidth:100,
    split:true,
    collapsible:true,
    store:Ext.create('Ext.data.TreeStore', {  
        id:'NavigationStore',
        root: {  
            expanded: true,  
            id:'all',
            text:'All',
            children: [  
                {text: "消息管理", id: "message-view", leaf: true},                  
                {text: "用户列表", id: "UserGrid", leaf: true}  
            ]  
        }  
    })
});

在app\view\main,新建总部内容ContentPanel.js,内容如下

Ext.define('MyApp.view.main.ContentPanel',{
    extend:'Ext.panel.Panel',
    xtype:'app-contentPanel',
    autoScroll:true
});

在app\view\user,新建用户页面UserGrid.js,内容如下

Ext.define('MyApp.view.user.UserGrid', {  
    extend: 'Ext.grid.Panel',  
    xtype: 'UserGrid',  
    title: '用户列表',  
    requires:['MyApp.store.UserStore'],
    store:Ext.create('MyApp.store.UserStore'),
    controller:'usergrid',
    initComponent:function(){
        var me = this;   
         me.columns = [
             {xtype: 'rownumberer',header: '序号', width: 60, align: 'center'},  
             {xtype: 'rownumberer',header: '用户名', width: 60, align: 'center'},  
             {xtype: 'rownumberer',header: '年龄', width: 60, align: 'center'},  
         ];
        me.callParent();
    },
    width: 400,  
    height:600,
    border:true,
    listeners:{
        itemdblclick: {  
            fn: 'userClick',  
            scope: "controller"  
        }  
    }
});  

 

 在app\view\user,新建用户视图控制器UserGridController.js,内容如下

Ext.define('MyApp.view.user.UserGridController',{
    extend:'Ext.app.ViewController',
    alias:'controller.usergrid',
    requires:["MyApp.view.user.UserGrid"],
    userClick:function( view, record, item, index, e, eOpts){  
        alert('hello'+record.get('name'))  
    } 
});

 

在app\model ,新建UserModel.js,内容如下

Ext.define('MyApp.model.UserModel', {  
    extend: 'Ext.data.Model',  
    fields: [  
        {name: 'name', type: 'string'},  
        {name: 'age',  type: 'int'},  
        {name: 'phone',  type: 'string'}  
    ]  
});  

 

在app\store,新建UserStore.js,内容如下

Ext.define('MyApp.store.UserStore', {  
    extend: 'Ext.data.Store',  
    model: 'MyApp.model.UserModel',  
    autoLoad: true,  
    alias:'user-store',
    proxy: {  
        type: 'ajax',  
        api: {  
            read: 'data/users.json'  
        },  
        reader: {  
            type: 'json',  
            rootProperty: 'users',  
            successProperty: 'success'  
        }  
    }  
});  

 需要注意事项:

1、文件目录必须按Ext.define的定义的顺序建立,这个是默认约定的,否则找不到文件Js;

2、导航的id值必须是和新建的控件名称的xtype类型对应,否则加载控件失败;

3、ViewController和View绑定,在Js里面requires的内容项,默认会加载相应的Js文件;

4、如果提示,extjs Cannot read property 'isBufferedStore' of undefined,主要原因在于store内容为空导致的;

完整代码如下

 DEMO下载

参考地址 Extjs5.0(6):控制器(Controller、ViewController)和路由器(Router)

转载于:https://www.cnblogs.com/xibei666/p/8447398.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值