EXT JS4 mvc模式及实例

来源:互联网 发布:淘宝客店铺设置 编辑:程序博客网 时间:2024/04/19 13:33
 

EXT JS4 mvc模式及实例


目录(?)[+]

有许多MVC体系结构,其中大多数都是彼此略有不同。这是EXT JS4中的。
    模型:字段和数据的集合。模型知道如何通过数据包存储,能通过协议连接到其他模型。
    视图:任何类型的组件——网格、树和面板是所有视图。    
    控制器:存放所有使应用程序工作的代码的地方——不管是渲染的视图,实例化模型,或任何其他应用程序逻辑。

一、文件结构

EXT JS4中应用遵循统一的目录结构,所以每一个应用程序都是相同的。在MVC布局中,所有的类都放在了app文件夹,该文件夹依次包含了存放模型、视图、控制器和存储的文件夹。

Folder Structure

二、实战代码

1.index.html

<html><head>    <title>Account Manager</title>    <link rel="stylesheet" type="text/css" href="ext-4.0/resources/css/ext-all.css">    <script type="text/javascript" src="ext-4.0/ext-debug.js"></script>    <script type="text/javascript" src="app.js"></script></head><body></body></html>

2.app.js

Ext.application({    requires: 'Ext.container.Viewport',    name: 'AM',    appFolder: 'app',    launch: function() {        Ext.create('Ext.container.Viewport', {            layout: 'fit',            items: [                {                    xtype: 'panel',                    title: 'Users',                    html : 'List of users will go here'                }            ]        });    }});

3.定义控制器

Users.js:

Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    init: function() {        console.log('Initialized Users! This happens before the Application launch function is called');    }});

添加新建的Users 控制器到app.js中的应用配置中:

Ext.application({    ...    controllers: [        'Users'    ],    ...});

当用应该程序在浏览器上访问 index.html 时,Users控制器会自控装载(因为我们指定它在应用定义以上),init 函数在应用程序的launch函数启动之前被调用。

init 函数是一个很棒的地方来来简历控制器如何与视图交互 ,通常是与另一个控制器函数——control结合使用。control函数使得它容易监听视图类中的事件,并对处理函数采取一些措施。更新ourUsers控制器,设定什么时候渲染面板,Users.js:

Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    init: function() {        this.control({            'viewport > panel': {                render: this.onPanelRendered            }        });    },    onPanelRendered: function() {        console.log('The panel was rendered');    }});
control函数使用ComponentQuery引擎,以快速方便地得到页面上的参考部件。'viewport > panel'可翻译成"find every Panel that is a direct child of a Viewport"。然后,我们提供了一个对象映射事件名(例子中只有渲染)处理功能。整体效果是无论何时任何组件匹配到选择器(即'viewport > panel')时,触发render事件,onPanelRendered函数被调用。

Controller listener

4.定义视图

视图通常定义成Ext .JS .component的子类,List.js
Ext.define('AM.view.user.List' ,{    extend: 'Ext.grid.Panel',    alias : 'widget.userlist',    title : 'All Users',    initComponent: function() {        this.store = {            fields: ['name', 'email'],            data  : [                {name: 'Ed',    email: 'ed@sencha.com'},                {name: 'Tommy', email: 'tommy@sencha.com'}            ]        };        this.columns = [            {header: 'Name',  dataIndex: 'name',  flex: 1},            {header: 'Email', dataIndex: 'email', flex: 1}        ];        this.callParent(arguments);    }});
我们有可能继承Grid Component,建立一个别名(alias),以便可以用它作为一个xtype。
然后添加这个视图到Users控制器中,由于我们用'widget.'格式设置了一个别名,我们可以用'userlist'作为一个xtype,就像先前用的'panel'一样。Users.js:
Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    views: [        'user.List'    ],    init: ...    onPanelRendered: ...});

通过修改app.js中的launch函数,把它渲染到主视图中:

Ext.application({    ...    launch: function() {        Ext.create('Ext.container.Viewport', {            layout: 'fit',            items: {                xtype: 'userlist'            }        });    }});
'user.List'告诉应用程序自动加载文件。

Our first View

5.控制网格

修改User.js:
Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    views: [        'user.List'    ],    init: function() {        this.control({            'userlist': {                itemdblclick: this.editUser            }        });    },    editUser: function(grid, record) {        console.log('Double clicked on ' + record.get('name'));    }});
我们改变了 ComponentQuery 选择器( 'userlist'),事件名称 ( 'itemdblclick'),处理函数名称 ('editUser')。

Edit.js
Ext.define('AM.view.user.Edit', {    extend: 'Ext.window.Window',    alias : 'widget.useredit',    title : 'Edit User',    layout: 'fit',    autoShow: true,    initComponent: function() {        this.items = [            {                xtype: 'form',                items: [                    {                        xtype: 'textfield',                        name : 'name',                        fieldLabel: 'Name'                    },                    {                        xtype: 'textfield',                        name : 'email',                        fieldLabel: 'Email'                    }                ]            }        ];        this.buttons = [            {                text: 'Save',                action: 'save'            },            {                text: 'Cancel',                scope: this,                handler: this.close            }        ];        this.callParent(arguments);    }});
我们再一次使用initComponent来指定复杂对象items和buttons。
添加视图到控制器,渲染并加载它。Users.js:
Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    views: [        'user.List',        'user.Edit'    ],    init: ...    editUser: function(grid, record) {        var view = Ext.widget('useredit');        view.down('form').loadRecord(record);    }});
我们用方法Ext.widget创建了一个视图,相当于Ext.create('widget.useredit')。然后我们用ComponentQuery再次快速获取一个编辑窗口的表单,在Ext JS 4中,每个组件都有一个down函数,该函数接受ComponentQuery选择器来找子组件。

6.创建一个模型和一个存储

app/store/Users.js

Ext.define('AM.store.Users', {    extend: 'Ext.data.Store',    fields: ['name', 'email'],    data: [        {name: 'Ed',    email: 'ed@sencha.com'},        {name: 'Tommy', email: 'tommy@sencha.com'}    ]});
让Users控制器加载时包括这个store,修改app/controller/Users.js:
Ext.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    stores: [        'Users'    ],    ...});
修改app/view/user/List.js
Ext.define('AM.view.user.List' ,{    extend: 'Ext.grid.Panel',    alias : 'widget.userlist',    //we no longer define the Users store in the `initComponent` method    store: 'Users',    ...});
app/model/User.js
Ext.define('AM.model.User', {    extend: 'Ext.data.Model',    fields: ['name', 'email']});
修改控制器和存储:
//the Users controller will make sure that the User model is included on the page and available to our appExt.define('AM.controller.Users', {    extend: 'Ext.app.Controller',    stores: ['Users'],    models: ['User'],    ...});// we now reference the Model instead of defining fields inlineExt.define('AM.store.Users', {    extend: 'Ext.data.Store',    model: 'AM.model.User',    data: [        {name: 'Ed',    email: 'ed@sencha.com'},        {name: 'Tommy', email: 'tommy@sencha.com'}    ]});

7.用模型保存数据

更新控制器,使它能监听save按钮:

Ext.define('AM.controller.Users', {    init: function() {        this.control({            'viewport > userlist': {                itemdblclick: this.editUser            },            'useredit button[action=save]': {                click: this.updateUser            }        });    },    updateUser: function(button) {        console.log('clicked the Save button');    }});
'useredit button[action=save]':用 'useredit' xtype来 聚焦道正在编辑的用户窗口,然后在窗口中寻找拥有'save' action的任何按钮。

编辑save按钮事件:

updateUser: function(button) {    var win    = button.up('window'),        form   = win.down('form'),        record = form.getRecord(),        values = form.getValues();    record.set(values);    win.close();}
button.up('window')找到正在编辑的用户窗口,win.down('form')找到表单

8.保存到服务器

使用ajax:

Ext.define('AM.store.Users', {    extend: 'Ext.data.Store',    model: 'AM.model.User',    autoLoad: true,    proxy: {        type: 'ajax',        url: 'data/users.json',        reader: {            type: 'json',            root: 'users',            successProperty: 'success'        }    }});
我们移除了'data'属性,用‘porxy’来代替。在EXT JS4中proxy是一种从一个store或模型中加载和保存数据的方法,有AJAX, JSON-P 和HTML5 porxy。例子中加载的数据来自于'data/users.json'

创建data/users.json

{    success: true,    users: [        {id: 1, name: 'Ed',    email: 'ed@sencha.com'},        {id: 2, name: 'Tommy', email: 'tommy@sencha.com'}    ]}
对proxy做一点小变化
proxy: {    type: 'ajax',    api: {        read: 'data/users.json',        update: 'data/updateUsers.json'    },    reader: {        type: 'json',        root: 'users',        successProperty: 'success'    }}
仍旧从users.json中读数据,但任何修改都会发送到updateUsers.json中。updateUsers.json文件中仅仅包含{"success": true}.
updateUser: function(button) {    var win    = button.up('window'),        form   = win.down('form'),        record = form.getRecord(),        values = form.getValues();    record.set(values);    win.close();    this.getUsersStore().sync();}
告诉store编辑之后,同步它自己。

The record in the grid has been updated

原创粉丝点击