Extjs MVC開發模式詳解

在JS的開發過程當中,大規模的JS腳本難以組織和維護,這一直是困擾前端開發人員的頭等問題。Extjs爲了解決這種問題,在Extjs 4.x版本中引入了MVC開發模式,開始將一個JS(Extjs)應用程序分割成Model-View-Controller三層,爲JS應用程序的如何組織代碼指明瞭方向,同時使得大規模JS代碼變得更加易於重用和維護;這就是Extjs MVC開發模式的初衷。html

在官方給出的MVC例子中,咱們能夠看到一個簡單的列表編輯功能,這篇文章就圍繞這個功能進行詳細的講解,讓咱們一塊兒來揭開Extjs MVC的神祕面紗!前端

本文的示例代碼適用於Extjs 4.x和Extjs 5.x,在Extjs 4.2.1 和Extjs 5.0.1中親測可用!mvc

 

常規開發模式下的列表編輯功能實現

咱們先來看一下這個例子,它的功能很是簡單:在頁面打開的時候加載一個列表,當雙擊列表中一行數據的時候打開編輯窗口,編輯完成以後點擊保存按鈕,而後更新列表。截圖以下:app

imageextjs-mvc-in-detailthis

在常規的開發模式下,要實現這個功能很是簡單,代碼以下:spa

Ext.onReady(function () {
    //1.定義Model
    Ext.define("MyApp.model.User", {
        extend: "Ext.data.Model",
        fields: [
            { name: 'name', type: 'string' },
            { name: 'age', type: 'int' },
            { name: 'phone', type: 'string' }
        ]
    });

    //2.建立store
    var store = Ext.create("Ext.data.Store", {
        model: "MyApp.model.User",
        data: [
            { name: "Tom", age: 5, phone: "123456" },
            { name: "Jerry", age: 3, phone: "654321" }
        ]
    });

    //3.建立grid
    var viewport = Ext.create("Ext.container.Viewport", {
        layout: "fit",
        items: {
            xtype: "grid",
            model: "MyApp.model.User",
            store: store,
            columns: [
                { text: '姓名', dataIndex: 'name' },
                { text: '年齡', dataIndex: 'age', xtype: 'numbercolumn', format: '0' },
                { text: '電話', dataIndex: 'phone' }
            ]
        }
    });

    //4.添加雙擊編輯
    var grid = viewport.down("grid");
    grid.on("itemdblclick", function (me, record, item, index, e, eopts) {
        //5.建立編輯表單
        var win = Ext.create("Ext.window.Window", {
            title: "編輯用戶",
            width: 300,
            height: 200,
            layout: "fit",
            items: {
                xtype: "form",
                margin: 5,
                border: false,
                fieldDefaults: {
                    labelAlign: 'left',
                    labelWidth: 60
                },
                items: [
                    { xtype: "textfield", name: "name", fieldLabel: "姓名" },
                    { xtype: "numberfield", name: "age", fieldLabel: "年齡" },
                    { xtype: "textfield", name: "phone", fieldLabel: "電話" }
                ]
            },
            buttons: [
                {
                    text: "保存", handler: function () {
                        win.down("form").updateRecord();
                        record.commit();
                        win.close();
                    }
                }
            ]
        });
        win.down("form").loadRecord(record);
        win.show();
    });
});

在這段代碼中,咱們用到了Model、Store、Grid,以及編輯的Window和Form。代碼中已經給出了簡單的註釋,這不是今天重點要介紹的。code

Extjs MVC開發模式

假設你歷來沒有接觸過Extjs MVC開發模式,可是你知道ASP.NET MVC、或者別的任何語言下的MVC開發模式,那麼咱們來試想一下Extjs下的MVC該是什麼樣子?orm

  1. JS是須要在html頁面中運行的,因此它要有一個宿主頁面
  2. 它要有Model、View和Controller三層,這是MVC的基礎,若是缺乏了這三層,那還叫什麼MVC呢?
  3. 這個JS程序可能須要有一個入口,由於JS不像ASP.NET那樣根據URL來分配Controller和Action

好了,咱們暫時想到了這麼多,那麼在實際的Extjs MVC開發過程當中是什麼樣子呢?咱們來看一下目錄結構:htm

第一步,建立入口頁面

建立一個html頁面,咱們使用mvc.html頁面,在這個頁面的同一個目錄,咱們建立一個app的文件夾,在這個文件夾下面用來放置js代碼。mvc.html就是咱們的程序宿主頁面。對象

image

 

第二步,建立目錄結構

在app文件夾下面建立controller、model、store和view文件夾,從名稱上就知道他們該放置什麼代碼了吧。而後建立Application.js做爲咱們程序的入口文件,並在mvc.html中引用Application.js文件。

image

第三步,建立model

在model文件夾下面,建立user.js文件:

image

這個文件將存放咱們的model,咱們能夠直接把最上面定義model的代碼賦值到這裏面。

app/model/User.js 的代碼以下:

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

第四步,建立store

雖然store不是mvc中必須的步驟,可是做爲數據倉庫,store起到了數據存取的做用,grid、form等展示的數據都是經過store來提供的,所以store在extjs mvc開發模式中是必不可少的。

image

app/store/user.js 的代碼以下:

Ext.define("MyApp.store.User", {
    extend: "Ext.data.Store",
    model: "MyApp.model.User",
    data: [
        { name: "Tom", age: 5, phone: "123456" },
        { name: "Jerry", age: 3, phone: "654321" }
    ]
});

第五步,建立view

爲了實現列表和編輯功能,咱們須要兩個視圖,分別是list和edit,那麼view的結構以下:

image

app/view/user/List.js 對應咱們的grid的定義,只不過將建立grid的實例改爲了建立grid的擴展。

app/view/user/List.js 代碼以下:

Ext.define("MyApp.view.user.List", {
    extend: "Ext.grid.Panel",
    alias: 'widget.userlist',
    store: "User",
    initComponent: function () {
        this.columns = [
            { text: '姓名', dataIndex: 'name' },
            { text: '年齡', dataIndex: 'age', xtype: 'numbercolumn', format: '0' },
            { text: '電話', dataIndex: 'phone' }
        ];
        this.callParent(arguments);
    }
});

app/view/user/edit.js 對應咱們的window的定義,但一樣是經過擴展的形式來實現的。

app/view/user/edit.js 代碼以下:

Ext.define("MyApp.view.user.Edit", {
    extend: "Ext.window.Window",
    alias: "widget.useredit",
    title: "編輯用戶",
    width: 300,
    height: 200,
    layout: "fit",

    items: {
        xtype: "form",
        margin: 5,
        border: false,
        fieldDefaults: {
            labelAlign: 'left',
            labelWidth: 60
        },
        items: [
            { xtype: "textfield", name: "name", fieldLabel: "姓名" },
            { xtype: "numberfield", name: "age", fieldLabel: "年齡" },
            { xtype: "textfield", name: "phone", fieldLabel: "電話" }
        ]
    },
    buttons: [
        { text: "保存", action: "save" }
    ]
});

注意:對於view類的建立,咱們須要定義alias,這是爲了方便咱們經過xtype來建立該組件的實例。(若是沒有alias,咱們將很難在viewport和controller中使用 —— 這是我爬過的坑!)

第六步,建立controller

controller做爲鏈接model、store和view的橋樑,在mvc開發模式中起到了相當重要的做用。若是說model定義了數據模式、store提供了數據存取的方法、view用來展現數據,那麼controller將用來控制具體的數據操做。

image

app/controller/user.js 的代碼以下:

Ext.define('MyApp.controller.User', {
    extend: 'Ext.app.Controller',
    stores: ['User'],
    models: ['User'],
    views: ['Viewport', 'user.List', 'user.Edit'],
    init: function () {
        this.control({
            'userlist': {
                itemdblclick: this.editUser
            },
            'useredit button[action=save]': {
                click: this.saveUser
            }
        });
    },
    editUser: function (grid, record) {
        var win = Ext.widget("useredit"); 
        win.down("form").loadRecord(record);
        win.show();
    },
    saveUser: function (btn) {
        var win = btn.up("window"),
            form = win.down("form"),
            record = form.getRecord();
        form.updateRecord();
        record.commit();
        win.close();
    }
});

咱們來詳細的說一下controller的這段代碼。在這段代碼中:

  1. 將定義好的model、store、view做爲配置項添加到controller中,controller會加載這些文件;
  2. 在init方法中爲view添加響應事件(這裏添加事件的方法是經過query方式獲取控件並添加的,這也是爲何要爲view添加alias的緣由)
  3. editUser方法和saveUser方法則是具體的操做內容

有了這些步驟,咱們就將model、store、view聯繫在一塊兒了。而後,咱們進入Application.js文件中,完善咱們的入口頁面。

第七步,完善Application.js文件

在不少時候,Application.js文件也被簡單的命名爲app.js,它們的做用是同樣的,爲應用程序提供一個入口。它能夠很簡單,咱們的Application.js文件代碼以下:

Ext.application({
    name: "MyApp",
    appFolder: 'app',
    controllers: ["User"],
    autoCreateViewport: true,
    launch: function () {
        // 頁面加載完成以後執行

    }
});
  • name: 應用程序名稱
  • appFolder: 應用程序代碼的目錄,用來進行動態加載代碼的
  • controllers: 應用程序使用到的控制器
  • autoCreateViewport: 是否自動建立Viewport,默認爲false,咱們這裏設置爲true,當它被設置爲true的時候,應用程序會自動建立Viewport,這個Viewport的定義在咱們的app/view/viewport.js 中;若是爲false的時候,咱們須要在launch中手動建立相應的視圖。

第八步,Viewport.js的定義

Viewport做爲咱們應用程序的視圖面板,能夠被單獨的定義在一個Viewport.js文件中。它的定義也很簡單,一般用來將一個或多個view做爲它的子控件。

app/view/viewport.js 代碼以下:

Ext.define("MyApp.view.Viewport", {
    extend: "Ext.container.Viewport",
    layout: "fit",
    items: {
        xtype:"userlist"
    }
});

完成這些步驟以後,咱們能夠運行mvc.html來查看效果。

總結

Extjs MVC開發模式爲咱們提供了一個完善的代碼組織和維護的方向,它的出發點是好的,可是在實際的操做過程當中,咱們會發現這種模式過於繁瑣,這多是因爲咱們的示例太過於簡單而形成的。

Extjs MVC的Model、Store、View、Controller各層的代碼都是經過Ext.define來建立類的形式完成的,所以在使用Extjs MVC以前,咱們須要對Extjs的類系統有必定的認識,包括如何使用Ext.define自定義類。

對於View層的控件,咱們須要爲它們指定一個alias屬性,方便經過xtype建立對象,並能夠在Controller中方便的找到他,爲它的子控件添加具體的操做。

相關文章
相關標籤/搜索