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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM