Sencha, the nightmare!

基礎

建立一個應用程序

sencha -sdk /path/to/sdk generate app %name% /path/to/apphtml

跑起來

cd /path/to/app程序員

sencha app watchweb

放心,出錯了會出紅字,本身退回命令行。數據庫

開瀏覽器,默認地址是 http://localhost:1841編程

在 watch 模式下,任何對源程序的修改都會自動更新,方便立刻看到效果。看起來還挺方便,可是由於過分的 js 對象化包裝,使得 Sencha 的應用調試起來無比困難。生產化打包編譯之後,更是隻有一個 app.js,萬一出錯了的話,你是找不到源頭的了。json

 

目錄結構

主要注意下面幾個文件夾瀏覽器

app

與具體平臺、設備分辨率無關的東東。好比下面要提到的數據模型、Store。服務器

想法挺好,但是缺少 IDE 支持的狀況下(其自家的開發工具還不支持 6.0.2 版本的 Sencha),在各個目錄之間跳轉切換是很是麻煩的。即使用了 file buffer,你也得記住文件 id。app

classic

經典 :) 聽上去像極了 IIS Classic。就是傳統的網頁應用程序。寫頁面視圖就在這裏,也是默認的實現。框架

modern

現代,與經典對應。平板和觸碰設備用。

packages

自定義的程序包,好比主題,就放在這裏。默認的界面主題若是不能知足須要,那麼就能夠自定義主題。雖然自定義是很是痛苦的。

resources

圖片,通用的文件放在這裏。

 

數據

Model

模型,或者叫數據模型,能夠看做數據庫存儲的結構映射。

定義一個數據模型,繼承自 Ext.data.Model

Ext.define("Inventory.model.Band",{
    extend:'Ext.data.Model',
    fields:[
        {name:'Id', type:'int'},
        {name:'Start', type:'float',allowBlank:false },
        {name:'End', type:'float',allowBlank:false},
        {name:'Wavelength', type:'string',allowBlank:false }
    ]
});

順便說一句,用不一樣文件夾來存放同一個功能模塊各個不一樣組件的作法很是落後。這本是用 IDE 和命名規範能夠輕易解決的問題。而在類名裏面加上文件夾的結構,則更是多餘:多繼承或者引用、實現抽象類的時候,多個文件夾結構你怎麼放、怎麼起名?

 

Store

存儲。實際上是存儲代理的定義,即,從哪兒讀取數據,又將數據寫回哪兒。

其 load 函數在數據讀取完成後回調,能夠對返回的數據作進一步處理,比較方便。須要綁定數據模型使用。

proxy 屬性指明瞭實際進行數據庫(存取)操做的服務地址,這裏也就出了 Sencha 的圈兒了,Spring 也能夠、ASP.NET 也能夠,隨意。

Ext.create('Ext.data.Store',{
    model:'Inventory.model.Band',
    id:'remotestore',
    proxy:{
        type : 'rest',
        url:'http://localhost:40544/Band.svc/GetBands',
        reader : {
            type : 'json',
            rootProperty : 'd'
        }
    },
    listeners:{
        load:function ( pageStore, records, successful , pageOperation , eOpts ){
            var bs = {bands:[]};
             for(var i=0;i<records.length;i++){
                 bs.bands.push(records[i].data);
             }
            Ext.getStore('bandstore').setData(bs);
        }
    }
});

ViewModel

視圖模型,即對頁面上所放字段的映射。能夠是數據模型的一部分,也能夠是多個關聯數據模型的組合。但其實 Sencha 這麼搞,是把簡單問題弄複雜了,由於 html 頁面自己就有表單和字段,直接 parse 其鍵值對便可;而如今則必須再從新定義一遍這些字段,等於一樣的定義在 html 表單和模型視圖裏面各自寫了一遍,重複了。

定義一個視圖模型

Ext.define('Inventory.view.main.MainModel', {
    extend: 'Ext.app.ViewModel',
    alias: 'viewmodel.main',
    data: {
        name: 'Inventory'
    }
});

使用的時候,首先在頁面裏面說明要用到的視圖模型是哪一個,而後對頁面上能夠 set 的屬性綁定視圖模型的字段,好比下面這個,綁定頁面的標題:

viewModel: 'main',
header: {
    title: {
        bind: {
            text: '{name}'
        }
    }
}

 

視圖

放在頁面上的可視區域,用來顯示內容、提供交互操做。相似 SharePoint 上面的 WebPart。可是 WebPart 的本意是讓用戶也能夠自定義頁面(這個想法也是挺天真),視圖則是讓程序員來自定義頁面(這個想法更是天真)。

建立一個新視圖,名字叫 band.Band,可是放在 main 文件夾裏面。這就是我前面說的,文件夾歸類法不靠譜的地方。

Ext.define('Inventory.view.band.Band', {
    extend: 'Ext.panel.Panel',
    xtype: 'bandview',
    items :[
        {html:'<h2>hello!</h2>'}
    ]
});

咱們也能夠用以前定義的視圖模型來動態地顯示點兒內容:

Ext.define('Inventory.view.band.Band', {
    extend: 'Ext.panel.Panel',
    xtype: 'bandview',
    viewModel: 'main',
    items :[
        {bind:{html:'<h2>hello,{name}!</h2>'}}
    ]
});

表單

下面來一個複雜點兒的視圖模型綁定,將 band 綁定到一個表單 form 上面:

{
    xtype: 'form',
    defaultType: 'textfield',
    viewModel: 'band', //this viewModel will provide default values.
    margin: '5, 0, 20, 0',
    items:[
        { name: 'Id', fieldLabel: 'Id', readOnly: true, bind: { value: '{Id}'} },
        { name: 'Wavelength', fieldLabel: 'Wavelength', bind: { value: '{Wavelength}'} },
        { name: 'Start', fieldLabel: 'Start', bind: { value: '{Start}'} },
        { name: 'End', fieldLabel: 'End', bind: { value: '{End}'} },
        { name: 'Reset', text: 'Reset', xtype: 'button', handler: function() { var form = this.up('form').getForm(); form.reset(); } }
    ]
}

滾動條

有的時候表單內容太多會超出窗口範圍,此時能夠用滾動條屬性(又一個重複的發明):

scrollable: true

列表

列表能夠用 store 綁定,哪怕這個 store 是從內存裏面讀取的預約義的數據。

Sencha 的文檔裏面對這種綁定描述甚少,值得批評。下面的例子,當選擇一條記錄的時候,自動將選中的值填充到前面的 form 裏面。

//a grid, using store to retreive data
{
    xtype: 'grid',
    border: true,
    width: 600,
    store: {type: 'bandstore' },
    columns: [
        { text: 'Id',  dataIndex: 'Id', width:100 },
        { text: 'Wavelength',  dataIndex: 'Wavelength', width:200 },
        { text: 'Start', dataIndex: 'Start', flex: 1, width:100 },
        { text: 'End', dataIndex: 'End', flex: 1, width:100 }
    ],
    listeners: {
        selectionchange: function(sm, selections){
            if(selections.length==0)return;
            var form = this.up('panel').down('form').getForm();
            form.setValues(selections[0].data);
        }
    }
}

固然,這不是列表和表單的經常使用方法,只是基礎。後面 Jony 會提供更復雜的玩兒法。

高級綁定

好比,上面的那個 listeners 裏面的 selectionchange 方法,實際上是能夠去掉的,只要這樣寫:

Ext.define('Inventory.view.band.Band', {
    extend: 'Ext.panel.Panel',
    xtype: 'bandview',
    viewModel: 'main',
    items :[
        //a random message showing viewmodel binding
        { bind: { html: '<h2>hello,{name}!</h2>' } },
        //a form, with viewmodel binding as well
        {
            xtype: 'form',
            defaultType: 'textfield',
            margin: '5, 0, 20, 0',
            items:[
                { name: 'Id', fieldLabel: 'Id', readOnly: true , bind: { value: '{bandgrid.selection.Id}'} },
                { name: 'Wavelength', fieldLabel: 'Wavelength' },//, bind: { value: '{Wavelength}'} },
                { name: 'Start', fieldLabel: 'Start' },//, bind: { value: '{Start}'} },
                { name: 'End', fieldLabel: 'End' },//, bind: { value: '{End}'} },
                { name: 'Reset', text: 'Reset', xtype: 'button', handler: function() { var form = this.up('form').getForm(); form.reset(); } }
            ]
        },
        //a grid, using store to retreive data
        {
            xtype: 'grid',
            reference: 'bandgrid',
            border: true,
            width: 600,
            store: {type: 'bandstore' },
            columns: [
                { text: 'Id',  dataIndex: 'Id', width:100 },
                { text: 'Wavelength',  dataIndex: 'Wavelength', width:200 },
                { text: 'Start', dataIndex: 'Start', flex: 1, width:100 },
                { text: 'End', dataIndex: 'End', flex: 1, width:100 }
            ]
        }
    ]
});

Sencha 的思想,是用編程的方式來粘合 Web 應用程序的組件,因此配置屬性就能工做是最好的,Sencha 的框架本身知道如何找到關聯數據並聯系起來。

嗯,想得挺好的。這麼作有一個前提:有完整的設計,且幾乎不會變動。

 

調試

若是不幸地,你的 Sencha 項目被集成進了某個服務器環境(好比 weblogic),那麼,單獨開一個並行的同類 Sencha 應用就變得很是有用了。

相關文章
相關標籤/搜索