Sencha Cmd創建Ext JS示例項目

Sencha提供了免費的Cmd工具,可以用來創建Ext JS項目并提供了一些便利的功能。
Sencha也在官方文檔中提供了一個示例來演示如何創建一個Sample Login App。
本文就介紹一下這個官網示例。

準備工作
  • 下載Sencha Ext JS的SDK,本文中使用的是開源的GPL的6.0.1版本
  • 下載Sencha Cmd,這個是免費的,本文中使用的是Windows 64-bit帶JRE的6.1.2版本

一些廢話:
也許Sencha是為了更好地推它的商用版本吧,從6.0.0版本開始,就把GPL版本的下載位置藏的很深,而且還需要通過發送郵件的方式來提供下載。

安裝
  • SDK解壓縮放到一個指定目錄,本文中為D:\ext-6.0.1
  • Cmd安裝到默認位置即可

一些廢話:
6.x版本從以前方便很多,如果你使用的是5.x版本,那還需要額外安裝JDK, ANT, Ruby, SASS, COMPASS,這里就不啰嗦了。

本文創建的示例項目的路徑為D:\TutorialApp


那我們開始創建程序吧。
打開cmd命令行,使用sencha [-sdk SDK所在目錄] generate app [-classic|-modern] AppName App目錄命令來創建項目。

sencha -sdk D:\ext-6.0.1 generate app -classic TutorialApp D:\TutorialApp
  • -sdk D:\ext-6.0.1指明Ext JS SDK的所在目錄,如果運行命令行的所在目錄就是SDK目錄(D:\ext-6.0.1),則可以省略
  • -classic|-modern可以省略,Ext JS的6.0版本其中一個主要的更新就是把Ext JS和Touch合并,在創建時可以選擇哪一種類型,classic對應Ext JS,而modern對應Touch。如果省略,則創建所謂的universal類型,即classic和modern并存。在本文中演示的是桌面端程序,所以我們選擇classic。
  • TutorialApp是項目名稱,也將作為該項目的namespace。
  • D:\TutorialApp是項目名錄

一些廢話:
運行命令后,可以去倒一杯水,起來活動活動,因為這個過程大概會持續幾分鐘。完成之后,看下TutorialApp目錄的大小,會發現大概500M,真夠大的。

從命令進入項目目錄D:\TutorialApp,并輸入命令sencha app watch

cd D:\TutorialApp
sencha app watch

一些廢話:
運行命令后,可以再起來活動活動。

sencha app watch會啟動內置的jetty服務器,可以使我們方便地通過http://localhost:1841/ 來查看頁面。而且watch會監聽項目目錄中的文件變化而自動build。

這時候打開http://localhost:1841/ 會看到Cmd自動創建的默認首頁長這樣子。6.x版新增加的Triton主題和以前的主題有明顯的不同。

打開D:\TutorialApp目錄,看下Cmd自動創建的目錄和文件:

.sencha/                        # 里面存放的大多都是配置相關的文件,一般不需要修改
ext/                            # Ext JS SDK的一份copy,所以才會這么大
index.html                      # 首頁
app.json                        # 項目主配置文件
app.js                          # 項目主程序
app/                            # 項目源碼目錄
    model/                      # Model目錄
    store/                      # Store目錄
    view/                       # View目錄
        main/                   # 首頁的目錄
            Main.js             # 首頁的View
            MainModel.js        # 首頁的ViewModel
            MainController.js   # 首頁的ViewController
    Application.js              # Ext.Application
packages/                       # Sencha Cmd packages
workspace.json                  # Workspace的描述文件
build/                          # 保存項目最終的build結果

還有一些目錄和文件沒有列舉出來,那些目錄和文件一般都不需要我們去修改,前期可以忽略。
對我們來說,最重要的目錄就是app目錄,這是項目的源碼目錄,我們寫的代碼都保存在里面。
app目錄下包含三個子目錄:

  • model: 保存Model對象,Cmd也提供了命令來創建Ext JS中的Model對象。比如User,它包含id,name,email三個字段。在命令行中運行:
cd D:\TutorialApp
sencha generate model user.User id:int,name,email

運行Cmd的命令需要先進入項目目錄,運行之后會看到model目錄里多了一個子目錄user,user目錄里有新建的User.js文件。

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

關于Ext JS的Model的具體用法,請參照官方API文檔:Ext.data.Model

  • store: Ext JS的Store可以理解為Model對應的數據集合,在Store中可以定義怎么去讀取Model。具體用法,請參照官方API文檔:Ext.data.Store
  • view:所有和UI相關的代碼都保存在這里,比如窗口,表格,圖表等??梢詾槊總€UI創建對應的ViewController(Ext.app.ViewController)和ViewModel(Ext.app.ViewModel)。

由于這個示例程序要演示的是創建一個登錄窗口,只有等登錄完成之后才會顯示首頁。所以首先要打開項目根目錄下的app.js,將和TutorialApp.view.main.Main相關的代碼刪除。修改后的app.js長這樣:

Ext.application({
    name: 'TutorialApp',
    extend: 'TutorialApp.Application
});

如果你仍然保持sencha app watch的運行狀態,則Cmd會檢測到你對app.js的修改。此時訪問首頁,就會看到一片空白。

接著來創建用戶的登錄窗口,它是長這樣子的:

可以在app\view目錄里手動創建login子目錄,并在login目錄下手動創建Login.js和LoginController.js。也可以在命令行中運行以下命令來讓Cmd自動創建:

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

-base參數用來設置創建的UI是哪種類型,由于我們要創建的是窗口,所以繼承的是Ext.window.Window。

Login.js是登錄窗口的代碼,最后長這樣:

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

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

LoginController.js是Login的Controller,最后長這樣:

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

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

    }
});

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

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讀取用戶登錄狀態
        loggedIn = localStorage.getItem("TutorialLoggedIn");
        //如果用戶已登錄,則顯示首頁,否則顯示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();
                }
            }
        );
    }
});

最后在首頁上加上一個Logout按鈕,修改后的app\main\Main.js長這樣:

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}'
        }
    }]
});

在首頁的對應的Controller,app\main\MainController.js中添加Logout對應的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') {
            //
        }
    },
    //點擊Logout按鈕
    onClickButton: function () {
        //刪除保存在localStorage中的登錄狀態
        localStorage.removeItem('TutorialLoggedIn');
        //刪除首頁
        this.getView().destroy();
        //創建Login窗口
        Ext.create({
            xtype: 'login'
        });
    }
});

寫代碼到此就完成了,運行sencha app build命令

cd D:\TutorialApp
sencha app build

運行結束后,在build目錄下會生成production子目錄,可以把該目錄下的TutorialApp目錄發布到其他服務器上,比如Apache HTTP Server的htdocs目錄里。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容