Ext編寫項(xiàng)目(sencha cmd創(chuàng)建項(xiàng)目)--轉(zhuǎn)載的

自從使用ext后,就感覺(jué)離不開(kāi)ext了,最初使用時(shí)候,感覺(jué)完全不順,不過(guò)寫啥都感覺(jué)不舒服,感覺(jué)為什么要用這么重,這么不方便的框架,太死板,不靈活。但是我錯(cuò)了,隨著慢慢使用熟了,對(duì)這個(gè)框架的功能更加了解了,就感覺(jué)確實(shí)是一個(gè)好庫(kù),不需要寫html,不需要寫css!直接編寫js即可,而且都是面向?qū)ο?,全部都是一個(gè)一個(gè)對(duì)象,而且自帶的各種組件,需要什么有什么,如果覺(jué)得不好還可以直接改組件功能和樣子。以前一個(gè)大靜態(tài)頁(yè)面切兩天,用ext一會(huì)功夫就完事了。本來(lái)打算自己寫的,但是還好搜索看了一下,就找到這篇了!非常詳細(xì)的說(shuō)明,從構(gòu)建項(xiàng)目,到修改代碼,都有。。 就感覺(jué)自己寫了估計(jì)也沒(méi)有這么詳細(xì),還是轉(zhuǎn)載復(fù)制吧。以后留著自己看。勿怪。 轉(zhuǎn)至-寫意悠悠。。。。。。。。。。

Sencha提供了免費(fèi)的Cmd工具,可以用來(lái)創(chuàng)建Ext JS項(xiàng)目并提供了一些便利的功能。Sencha也在官方文檔中提供了一個(gè)示例來(lái)演示如何創(chuàng)建一個(gè)Sample Login App。本文就介紹一下這個(gè)官網(wǎng)示例。

準(zhǔn)備工作

下載Sencha Ext JS的SDK,本文中使用的是開(kāi)源的GPL的6.0.1版本
??下載Sencha Cmd,這個(gè)是免費(fèi)的,本文中使用的是Windows 64-bit帶JRE的6.1.2版本

安裝

SDK解壓縮放到一個(gè)指定目錄,如:D:\ext-6.0.1
??Cmd安裝到默認(rèn)位置即可

本文創(chuàng)建的示例項(xiàng)目的路徑為D:\TutorialApp

那我們開(kāi)始創(chuàng)建程序吧。
打開(kāi)cmd命令行,使用sencha [-sdk SDK所在目錄](méi) generate app [-classic|-modern] AppName App目錄命令來(lái)創(chuàng)建項(xiàng)目。

sencha -sdk D:\ext-6.0.1 generate app -classic TutorialApp D:\TutorialApp
  1. -sdk D:\ext-6.0.1指明Ext JS SDK的所在目錄,如果運(yùn)行命令行的所在目錄就是SDK目錄(D:\ext-6.0.1),則可以省略
  2. -classic|-modern可以省略,Ext JS的6.0版本其中一個(gè)主要的更新就是把Ext JS和Touch合并,在創(chuàng)建時(shí)可以選擇哪一種類型,classic對(duì)應(yīng)Ext JS,而modern對(duì)應(yīng)Touch。如果省略,則創(chuàng)建所謂的universal類型,即classic和modern并存。在本文中演示的是桌面端程序,所以我們選擇classic。
  3. TutorialApp是項(xiàng)目名稱,也將作為該項(xiàng)目的namespace。
  4. D:\TutorialApp是項(xiàng)目名錄
從命令進(jìn)入項(xiàng)目目錄D:\TutorialApp,并輸入命令sencha app watch
cd D:\TutorialApp
sencha app watch

sencha app watch會(huì)啟動(dòng)內(nèi)置的jetty服務(wù)器,可以使我們方便地通過(guò)http://localhost:1841/ 來(lái)查看頁(yè)面。而且watch會(huì)監(jiān)聽(tīng)項(xiàng)目目錄中的文件變化而自動(dòng)build。
這時(shí)候打開(kāi)http://localhost:1841/ 會(huì)看到Cmd自動(dòng)創(chuàng)建的默認(rèn)首頁(yè)長(zhǎng)這樣子。6.x版新增加的Triton主題和以前的主題有明顯的不同。

image.png
打開(kāi)D:\TutorialApp目錄,看下Cmd自動(dòng)創(chuàng)建的目錄和文件:
.sencha/                        # 里面存放的大多都是配置相關(guān)的文件,一般不需要修改
ext/                            # Ext JS SDK的一份copy,所以才會(huì)這么大
index.html                      # 首頁(yè)
app.json                        # 項(xiàng)目主配置文件
app.js                          # 項(xiàng)目主程序
app/                            # 項(xiàng)目源碼目錄
    model/                      # Model目錄
    store/                      # Store目錄
    view/                       # View目錄
        main/                   # 首頁(yè)的目錄
            Main.js             # 首頁(yè)的View
            MainModel.js        # 首頁(yè)的ViewModel
            MainController.js   # 首頁(yè)的ViewController
    Application.js              # Ext.Application
packages/                       # Sencha Cmd packages
workspace.json                  # Workspace的描述文件
build/                          # 保存項(xiàng)目最終的build結(jié)果

還有一些目錄和文件沒(méi)有列舉出來(lái),那些目錄和文件一般都不需要我們?nèi)バ薷模捌诳梢院雎浴?br> 對(duì)我們來(lái)說(shuō),最重要的目錄就是app目錄,這是項(xiàng)目的源碼目錄,我們寫的代碼都保存在里面。
app目錄下包含三個(gè)子目錄:
model: 保存Model對(duì)象,Cmd也提供了命令來(lái)創(chuàng)建Ext JS中的Model對(duì)象。比如User,它包含id,name,email三個(gè)字段。在命令行中運(yùn)行:

cd D:\TutorialApp
sencha generate model user.User id:int,name,email

運(yùn)行Cmd的命令需要先進(jìn)入項(xiàng)目目錄,運(yùn)行之后會(huì)看到model目錄里多了一個(gè)子目錄user,user目錄里有新建的User.js文件。

app/                          # 項(xiàng)目源碼目錄
  model/                      # Model目錄
      user/                   # user子目錄
          User.js             # User.js定義了User的字段

關(guān)于Ext JS的Model的具體用法,請(qǐng)參照官方API文檔:Ext.data.Model

store: Ext JS的Store可以理解為Model對(duì)應(yīng)的數(shù)據(jù)集合,在Store中可以定義怎么去讀取Model。具體用法,請(qǐng)參照官方API文檔:Ext.data.Store
view:所有和UI相關(guān)的代碼都保存在這里,比如窗口,表格,圖表等。可以為每個(gè)UI創(chuàng)建對(duì)應(yīng)的ViewController(Ext.app.ViewController)和ViewModel(Ext.app.ViewModel)。

由于這個(gè)示例程序要演示的是創(chuàng)建一個(gè)登錄窗口,只有等登錄完成之后才會(huì)顯示首頁(yè)。所以首先要打開(kāi)項(xiàng)目根目錄下的app.js,將和TutorialApp.view.main.Main相關(guān)的代碼刪除。修改后的app.js長(zhǎng)這樣:
Ext.application({
    name: 'TutorialApp',
    extend: 'TutorialApp.Application
});

如果你仍然保持sencha app watch的運(yùn)行狀態(tài),則Cmd會(huì)檢測(cè)到你對(duì)app.js的修改。此時(shí)訪問(wèn)首頁(yè),就會(huì)看到一片空白。

接著來(lái)創(chuàng)建用戶的登錄窗口,它是長(zhǎng)這樣子的:

image.png

可以在app\view目錄里手動(dòng)創(chuàng)建login子目錄,并在login目錄下手動(dòng)創(chuàng)建Login.js和LoginController.js。也可以在命令行中運(yùn)行以下命令來(lái)讓Cmd自動(dòng)創(chuàng)建:

cd D:\TutorialApp
sencha generate view -base Ext.window.Window login.Login

-base參數(shù)用來(lái)設(shè)置創(chuàng)建的UI是哪種類型,由于我們要?jiǎng)?chuàng)建的是窗口,所以繼承的是Ext.window.Window。

Login.js是登錄窗口的代碼,最后長(zhǎng)這樣:

Ext.define('TutorialApp.view.login.Login', {
    extend: 'Ext.window.Window',
    xtype: 'login',

    //Login窗口會(huì)包含一個(gè)表單(Ext.form.Panel)
    //LoginController里定義了Login窗口會(huì)使用到的方法onLoginClick
    //requires可以確保這2個(gè)類會(huì)在Login初始化完成之前先被初始化
    requires: [
        'TutorialApp.view.login.LoginController',
        'Ext.form.Panel'
    ],
    //綁定controller,綁定時(shí)使用的是別名
    controller: 'login',
    //padding: 10px
    bodyPadding: 10,
    //窗口的標(biāo)題欄文字
    title: 'Login Window',
    //隱藏窗口右上角的關(guān)閉按鈕"x"
    closable: false,
    //Window的autoShow默認(rèn)為false
    //Window可以用show()和hide()來(lái)手動(dòng)顯示和隱藏
    //把a(bǔ)utoShow設(shè)為true, 則在Window創(chuàng)建之后會(huì)自動(dòng)顯示
    autoShow: true,
    //把窗口里的UI組件放在items里
    items: {
        //表單
        xtype: 'form',
        reference: 'form',
        //把表單里的UI組件放在表單的items里
        items: [{
            //供用戶輸入用戶名的文本框
            xtype: 'textfield',
            name: 'username',
            //fieldLabel是顯示在文本框前的標(biāo)簽文字
            fieldLabel: 'Username',
            //打開(kāi)非空校驗(yàn),即要求輸入的用戶名不能為空
            allowBlank: false
        }, {
            //供用戶輸入密碼的文本框
            xtype: 'textfield',
            name: 'password',
            //inputType設(shè)為password,則用戶輸入的內(nèi)容會(huì)以*回顯在屏幕上
            inputType: 'password',
            fieldLabel: 'Password',
            allowBlank: false
        }, {
            //顯示在密碼輸入框下方的文字
            xtype: 'displayfield',
            hideEmptyLabel: false,
            value: 'Enter any non-blank password'
        }],
        //表單的按鈕
        buttons: [{
            //按鈕上的顯示文字
            text: 'Login',
            //設(shè)為true,則Login按鈕在表單通過(guò)校驗(yàn)前是不能被點(diǎn)擊的
            formBind: true,
            listeners: {
                //當(dāng)按鈕被點(diǎn)擊時(shí)
                click: 'onLoginClick'
            }
        }]
    }
});

LoginController.js是Login的Controller,最后長(zhǎng)這樣:

Ext.define('TutorialApp.view.login.LoginController', {
    extend: 'Ext.app.ViewController',
    //定義別名為login
    alias: 'controller.login',
    //當(dāng)Login按鈕被點(diǎn)擊時(shí)
    onLoginClick: function() {

        //這本例中使用localStorage來(lái)保存用戶的登錄狀態(tài)
        //這里省略了用戶信息的遠(yuǎn)程校驗(yàn)過(guò)程
        //只要用戶輸入用戶名和密碼,點(diǎn)擊Login按鈕即認(rèn)為用戶成功登陸
        localStorage.setItem("TutorialLoggedIn", true);
        //getView()返回的是controller綁定的view, 在本例中就是Login窗口
        //登錄后不再需要Login窗口,所以調(diào)用destroy()來(lái)刪除
        this.getView().destroy();
        //關(guān)閉Login窗口后,需要顯示首頁(yè)
        //使用Ext.create()來(lái)創(chuàng)建view\main\Main.js
        Ext.create({
            xtype: 'app-main'
        });

    }
});

登錄窗口寫好了,但還不會(huì)顯示,需要修改app\Application.js。
Application.js最后長(zhǎng)這樣:

Ext.define('TutorialApp.Application', {
    extend: 'Ext.app.Application',

    name: 'TutorialApp',

    stores: [
        // TODO: add global / shared stores here
    ],

    views: [
        'TutorialApp.view.login.Login',
        'TutorialApp.view.main.Main'
    ],

    launch: function () {
        var loggedIn;
        //從localStorage讀取用戶登錄狀態(tài)
        loggedIn = localStorage.getItem("TutorialLoggedIn");
        //如果用戶已登錄,則顯示首頁(yè),否則顯示Login窗口
        Ext.create({
            xtype: loggedIn ? 'app-main' : 'login'
        });
    },

    onAppUpdate: function () {
        Ext.Msg.confirm('Application Update', 'This application has an update, reload?',
            function (choice) {
                if (choice === 'yes') {
                    window.location.reload();
                }
            }
        );
    }
});

最后在首頁(yè)上加上一個(gè)Logout按鈕,修改后的app\main\Main.js長(zhǎng)這樣:

Ext.define('TutorialApp.view.main.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'app-main',

    requires: [
        'Ext.plugin.Viewport',
        'Ext.window.MessageBox',

        'TutorialApp.view.main.MainController',
        'TutorialApp.view.main.MainModel',
        'TutorialApp.view.main.List'
    ],

    controller: 'main',
    viewModel: 'main',
    plugins: 'viewport',

    ui: 'navigation',

    tabBarHeaderPosition: 1,
    titleRotation: 0,
    tabRotation: 0,

    header: {
        layout: {
            align: 'stretchmax'
        },
        title: {
            bind: {
                text: '{name}'
            },
            flex: 0
        },
        iconCls: 'fa-th-list',
        //添加Logout按鈕
        items: [{
            xtype: 'button',
            text: 'Logout',
            margin: '10 0',
            handler: 'onClickButton'
        }]
    },

    tabBar: {
        flex: 1,
        layout: {
            align: 'stretch',
            overflowHandler: 'none'
        }
    },

    responsiveConfig: {
        tall: {
            headerPosition: 'top'
        },
        wide: {
            headerPosition: 'left'
        }
    },

    defaults: {
        bodyPadding: 20,
        tabConfig: {
            plugins: 'responsive',
            responsiveConfig: {
                wide: {
                    iconAlign: 'left',
                    textAlign: 'left'
                },
                tall: {
                    iconAlign: 'top',
                    textAlign: 'center',
                    width: 120
                }
            }
        }
    },

    items: [{
        title: 'Home',
        iconCls: 'fa-home',
        items: [{
            xtype: 'mainlist'
        }]
    }, {
        title: 'Users',
        iconCls: 'fa-user',
        bind: {
            html: '{loremIpsum}'
        }
    }, {
        title: 'Groups',
        iconCls: 'fa-users',
        bind: {
            html: '{loremIpsum}'
        }
    }, {
        title: 'Settings',
        iconCls: 'fa-cog',
        bind: {
            html: '{loremIpsum}'
        }
    }]
});

在首頁(yè)的對(duì)應(yīng)的Controller,app\main\MainController.js中添加Logout對(duì)應(yīng)的click方法

Ext.define('TutorialApp.view.main.MainController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.main',

    onItemSelected: function (sender, record) {
        Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
    },

    onConfirm: function (choice) {
        if (choice === 'yes') {
            //
        }
    },
    //點(diǎn)擊Logout按鈕
    onClickButton: function () {
        //刪除保存在localStorage中的登錄狀態(tài)
        localStorage.removeItem('TutorialLoggedIn');
        //刪除首頁(yè)
        this.getView().destroy();
        //創(chuàng)建Login窗口
        Ext.create({
            xtype: 'login'
        });
    }
});

運(yùn)行sencha app build命令

cd D:\TutorialApp
sencha app build testing
sencha app build
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容