Extjs 4.2.0 MVC教程_第1頁(yè)
Extjs 4.2.0 MVC教程_第2頁(yè)
Extjs 4.2.0 MVC教程_第3頁(yè)
Extjs 4.2.0 MVC教程_第4頁(yè)
Extjs 4.2.0 MVC教程_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Extjs 4.2.0 MVC 架構(gòu)內(nèi)容:1. 文件結(jié)構(gòu)2. 創(chuàng)建項(xiàng)目3. 定義控制器4. 定義視圖5. 控制Grid6. 創(chuàng)建Model和Store7. 通過(guò)Model保存數(shù)據(jù)8. 保存到服務(wù)器端大型客戶(hù)端程序通常都難寫(xiě),難組織,難以維護(hù)。項(xiàng)目經(jīng)常由于增加功能,增加開(kāi)發(fā)人員而很快失控。Ext JS 4提出新的項(xiàng)目結(jié)構(gòu),不僅組織你的代碼,并且減少代碼量。我們的系統(tǒng)結(jié)構(gòu)延續(xù)“類(lèi)MVC模式”,第一次引入Models(模型)和Controllers(控制器)的概念?,F(xiàn)在有很多MVC架構(gòu),他們或多或少有細(xì)微差別。以下是我們對(duì)MVC的定義:· Model是字段和對(duì)應(yīng)數(shù)據(jù)的組合(例如User M

2、odel有username和password兩個(gè)字段)。Models知道如何通過(guò)數(shù)據(jù)包(data package)持久化,還可以通過(guò)associations(聯(lián)系)同其他models關(guān)聯(lián)。Models很類(lèi)似于Ext Js 3里的Record類(lèi),通常與Stores一起將數(shù)據(jù)展現(xiàn)到grids和其他components上。· View可以是任何類(lèi)型的component,grids, trees和panels都是視圖。· Controllers 是一個(gè)特殊的地方,用來(lái)放使application工作的代碼 - 可以是渲染視圖的,初始化models的,或者其他的應(yīng)用邏輯。在這篇文檔中我

3、們將創(chuàng)建一個(gè)管理用戶(hù)數(shù)據(jù)的簡(jiǎn)單應(yīng)用,最終你將指導(dǎo)如何使用Ext JS 4應(yīng)用架構(gòu)去組織你的應(yīng)用。對(duì)系統(tǒng)架構(gòu)來(lái)說(shuō),提供結(jié)構(gòu)和保持一致性,與實(shí)際的類(lèi)和framework代碼同樣重要。遵循我們的慣例可以帶來(lái)一系列非常重要的好處:· 所有的應(yīng)用都以同一種方式工作,所以你只需要學(xué)習(xí)一次。· 不同應(yīng)用之間可以共享代碼,因?yàn)樗麄兌家酝N方式工作· 你可以用我們的build工具來(lái)創(chuàng)建你的系統(tǒng)的優(yōu)化版本供production使用1. 文件結(jié)構(gòu)-Ext JS 4 對(duì)所有應(yīng)用定義相同的目錄結(jié)構(gòu)。關(guān)于應(yīng)用的基本文件結(jié)構(gòu)的詳細(xì)解釋請(qǐng)參考Getting Started Guide. 應(yīng)用MV

4、C結(jié)構(gòu),所有的類(lèi)都在app/文件夾下,依次包含子文件夾來(lái)命名你的models, views, controllers和stores。以下是我們做完這個(gè)簡(jiǎn)單的例子后,最終的文件結(jié)構(gòu):在這個(gè)例子里,我們將整個(gè)application放到”account_manager”文件夾下,Ext JS 4 SDK里的必要文件放到 ext-4/文件夾下。因此我們的index.hmtl內(nèi)容如下:<html><head> <title>Account Manager</title> <link rel="stylesheet" type=&q

5、uot;text/css" href="ext-4/resources/css/ext-all.css"> <script type="text/javascript" src="ext-4/ext-debug.js"></script> <script type="text/javascript" src="app.js"></script></head><body></body></ht

6、ml>2.在app.js里創(chuàng)建項(xiàng)目Ext JS 4的所有應(yīng)用都以Application這個(gè)實(shí)例作為入口。Application里包含你的應(yīng)用的全局設(shè)置(例如應(yīng)用的名稱(chēng)),并且維護(hù)此應(yīng)用中所有models, views 和controllers的引用。Application同事包含launch方法,這個(gè)方法在加載時(shí)自動(dòng)運(yùn)行?,F(xiàn)在讓我們創(chuàng)建一個(gè)簡(jiǎn)單的Account Manager應(yīng)用來(lái)幫助我們管理用戶(hù)賬號(hào)。首先我們定義一個(gè)全局namespace。所有Ext JS的應(yīng)用程序應(yīng)該只使用一個(gè)單一的全局變量,應(yīng)用所有的類(lèi)都嵌套在這個(gè)全局變量中。通常我們希望這個(gè)全局變量短一點(diǎn),所以在這個(gè)例子里我們使用

7、“AM“: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' );

8、 );這里發(fā)生了幾件事情。首先我們invoke(觸發(fā))了Ext.application來(lái)創(chuàng)建一個(gè)Application類(lèi)的實(shí)例,傳了一個(gè)名稱(chēng)“AM“給它。這將自動(dòng)為我們創(chuàng)建一個(gè)全局變量AM,代表由”appFoder”配置的“app”文件夾,并將這個(gè)namespace注冊(cè)到Ext.Loader。其次,為我們提供了一個(gè)簡(jiǎn)單的launch方法,創(chuàng)建了一個(gè)Viewport, 這個(gè)Viewport包含一個(gè)填充整個(gè)screen的Panel。3.定義控制器 Controllers-控制器是用來(lái)綁定整個(gè)application的膠水。它們真正做的就是監(jiān)聽(tīng)視圖(通常來(lái)自于視圖)以及做出響應(yīng)。接著Account M

9、anager這個(gè)例子,我們創(chuàng)建一個(gè)控制器。在app/Controller下創(chuàng)建一個(gè)User.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'); );現(xiàn)在讓我們?cè)赼pp.js里加上剛創(chuàng)建的Users 控制器:Ext.applica

10、tion( . controllers: 'Users' , .);當(dāng)我們?cè)跒g覽器里訪(fǎng)問(wèn)index.html時(shí),Users控制器會(huì)自動(dòng)加載(因?yàn)榍懊嫖覀冊(cè)贏pplication里指定了),init方法在Application的launch方法之前被調(diào)用。Init方法用來(lái)定義你的controller和view如何交互,通常與”control”這個(gè)控制器方法一起使用?!眂ontrol”方法用來(lái)監(jiān)聽(tīng)視圖類(lèi)的事件,以handler方法來(lái)控制行為?,F(xiàn)在讓我們更新Users控制器來(lái)告訴我們panel是什么時(shí)候被渲染的。Ext.define('AM.controller.Users&

11、#39;, extend: 'Ext.app.Controller', init: function() this.control( 'viewport > panel': render: this.onPanelRendered ); , onPanelRendered: function() console.log('The panel was rendered'); );我們更新了init方法,以this.control方法來(lái)監(jiān)聽(tīng)視圖。Control方法使用了新的組件查詢(xún)(ComponentQuery)機(jī)制,可以快速方便地獲得頁(yè)面組件

12、的引用。如果你對(duì)ComponentQuery不熟悉,請(qǐng)參考ComponentQuery Documentation里的詳細(xì)解釋。簡(jiǎn)單說(shuō)來(lái),它使我們傳類(lèi)似CSS的選擇器就可以找到頁(yè)面上所有匹配的組件。在init方法里我們使用了viewport > panel ,被解析成“找出viewport的所有為Panel的直接子組件“。然后我們提供一個(gè)處理對(duì)象,對(duì)應(yīng)事件名(在這個(gè)例子里是render)。效果是,當(dāng)任何匹配選擇器的組件觸發(fā)render事件時(shí),都將調(diào)用onPanelRendered方法?,F(xiàn)在啟動(dòng)我們的程序可以看到以下效果:雖然不像其它很多程序那樣讓人興奮,但這個(gè)例子體現(xiàn)了開(kāi)始組織代碼是如此

13、簡(jiǎn)單?,F(xiàn)在給我們的程序加上一個(gè)grid.4.定義視圖-截止到目前為止,我們的程序只有兩個(gè)文件,app.js和app/controller/User.js。現(xiàn)在我們想增加一個(gè)grid現(xiàn)實(shí)所有用戶(hù),是時(shí)候更好地組織我們的邏輯,并開(kāi)始使用視圖了。View其實(shí)也是組件,通常被定義為Ext JS組件的子類(lèi)。我們創(chuàng)建一個(gè)新文件app/view/user/List.js,加上一下代碼:Ext.define('AM.view.user.List' , extend: 'Ext.grid.Panel', alias: 'widget.userlist', titl

14、e: 'All Users', initComponent: function() this.store = fields: 'name', 'email', data : name: 'Ed', email: 'ed', name: 'Tommy', email: 'tommy' ; this.columns = header: 'Name', dataIndex: 'name', flex: 1, header: 'Email',

15、dataIndex: 'email', flex: 1 ; this.callParent(arguments); );我們的View類(lèi)不過(guò)是一個(gè)普通類(lèi)。在這個(gè)例子里我們繼承了Grid組件,設(shè)置一個(gè)別名,這樣我們就能把它作為xtype使用了(后面會(huì)講到)。同時(shí)我們?cè)O(shè)置了grid渲染所需的store和columns參數(shù)。接下來(lái)我們需要把這個(gè)視圖加到User控制器里。因?yàn)槲覀冊(cè)O(shè)置了“widget.”這種形式的別名,我們就可以像之前使用”panel”那樣將userlist作為xtype使用。Ext.define('AM.controller.Users', exten

16、d: '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' ); );這里還需要注意的是,我們?cè)谝晥D數(shù)組里指定user.list。這是告訴程序自動(dòng)加載這個(gè)文

17、件,這樣當(dāng)啟動(dòng)時(shí)我們就可以它。程序使用了Ext JS 4的新自動(dòng)加載系統(tǒng),從服務(wù)器端自動(dòng)獲取此文件?,F(xiàn)在刷新頁(yè)面可以看到如下效果:5.控制Grid-注意onPanelRendered方法仍會(huì)被調(diào)用。因?yàn)間rid類(lèi)仍滿(mǎn)足 viewport > panel 的條件。因?yàn)槲覀兊念?lèi)繼承Grid,從而也繼承了Panel。此時(shí),我們給這個(gè)選擇器增加的監(jiān)聽(tīng)事件會(huì)被所有viewport的直接子組件調(diào)用,如果這個(gè)子組件是Panel或Panel子類(lèi)。為了使程序邏輯更嚴(yán)謹(jǐn),我們用xtype來(lái)指定。這里我們監(jiān)聽(tīng)雙擊grid的行,然后編輯用戶(hù)。Ext.define('AM.controller.Users

18、', 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'); );注意我們把選擇器改成了更簡(jiǎn)單的userlist,事件名改成了itemdb

19、click”, 事件處理方法改成了editUser。 這里當(dāng)我們雙擊用戶(hù)時(shí),打印出用戶(hù)名。在控制臺(tái)打印出來(lái)也不錯(cuò),不過(guò)我們實(shí)際想坐的是編輯用戶(hù)。讓我們實(shí)現(xiàn)這個(gè)功能吧,增加一個(gè)新視圖app/view/user/Edit.js:Ext.define('AM.view.user.Edit', extend: 'Ext.window.Window', alias: 'widget.useredit', title: 'Edit User', layout: 'fit', autoShow: true, initCompon

20、ent: 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

21、', scope: this, handler: this.close ; this.callParent(arguments); );這次我們繼承自另一個(gè)已存在的組件 Ext.window.Window. 我們?nèi)允褂胕nitComonent指定更復(fù)雜的items和buttons對(duì)象。我們使用了fit的布局方式,和一個(gè)包含了編輯姓名、郵箱地址的form。然后我們創(chuàng)建了兩個(gè)按鈕,一個(gè)用來(lái)關(guān)閉窗口,一個(gè)用來(lái)保存我們的改動(dòng)。我們需要做的就是把view加到控制器里,渲染,并加載用戶(hù)。Ext.define('AM.controller.Users', extend: 'E

22、xt.app.Controller', views: 'user.List', 'user.Edit' , init: . editUser: function(grid, record) var view = Ext.widget('useredit'); view.down('form').loadRecord(record); );這里我們通過(guò)一個(gè)非常方便的方法 Ext.widget來(lái)創(chuàng)建視圖,這個(gè)方法等同于 Ext.create(widget.useredit). 然后我們?cè)俅问褂昧薈omponentQuery獲得

23、編輯窗口的引用。所有Ext JS 4組件都有一個(gè) down方法,這個(gè)方法可以用ComponentQuery快速找到所有子組件。雙擊grid的行,現(xiàn)在像這樣:6.創(chuàng)建Model和Store-現(xiàn)在已經(jīng)有了編輯框,是時(shí)候編輯用戶(hù)并保存了。在此之前,我們重構(gòu)一下我們的代碼。現(xiàn)在AM.view.user.List組件是在內(nèi)部創(chuàng)建的Store.這樣也可以運(yùn)行,但我們更希望引用其它地方的Store,這樣我們就可以更改里面的數(shù)據(jù)了。我們將把Store拆分到屬于它自己的文件里 app/store/Users.js:Ext.define('AM.store.Users', extend: '

24、;Ext.data.Store', fields: 'name', 'email', data: name: 'Ed', email: 'ed', name: 'Tommy', email: 'tommy' );然后我們需要做兩個(gè)小改動(dòng),首先我們要在控制器里加入這個(gè)Store:Ext.define('AM.controller.Users', extend: 'Ext.app.Controller', stores: 'Users' , .);

25、然后我們更新app/view/user/List.js,通過(guò)id引用Store:Ext.define('AM.view.user.List' , extend: 'Ext.grid.Panel', alias: 'widget.userlist', title: 'All Users', / we no longer define the Users store in the initComponent method store: 'Users', initComponent: function() this.co

26、lumns = .);通過(guò)在Users控制器加了store,store就能自動(dòng)加載到頁(yè)面,并且可以在view里應(yīng)用它(這個(gè)例子里只需簡(jiǎn)單配置store:Users)。此時(shí),fields(name和email)是在store內(nèi)部定義的。在Ext JS 4里我們有功能強(qiáng)大的Ext.data.Model,我們?cè)诰庉嬘脩?hù)時(shí)可以使用它。讓我們使用Model重構(gòu)Store,將以下代碼放到app/model/User.js里。Ext.define('AM.model.User', extend: 'Ext.data.Model', fields: 'name'

27、, 'email');這就是我們定義Model所需要做的。先讓我們更新Store,引用Model名而不是提供內(nèi)部fields定義:Ext.define('AM.store.Users', extend: 'Ext.data.Store', model: 'AM.model.User', data: name: 'Ed', email: 'ed', name: 'Tommy', email: 'tommy' );我們還需要在Users控制器里引用User Model:E

28、xt.define('AM.controller.Users', extend: 'Ext.app.Controller', stores: 'Users', models: 'User', .);重構(gòu)只是讓接下來(lái)的部分更簡(jiǎn)單,但對(duì)程序現(xiàn)在的行為不會(huì)有影響。如果我們刷新頁(yè)面,雙擊一行,我們可以看到編輯用戶(hù)窗口仍然彈出。接下來(lái)是時(shí)候完成編輯的功能了:7.通過(guò)Model保存數(shù)據(jù)-現(xiàn)在我們已經(jīng)有一個(gè)用戶(hù)grid加載數(shù)據(jù),雙擊一行用戶(hù)可以打開(kāi)編輯窗口,我們希望可以保存對(duì)用戶(hù)信息的更改。編輯用戶(hù)的窗口包含一個(gè)form(里面有姓名有荷香地址)

29、和一個(gè)保存按鈕。首先我們更新下控制器的init方法監(jiān)聽(tīng)save按鈕的單擊事件。Ext.define('AM.controller.Users', . init: function() this.control( 'viewport > userlist': itemdblclick: this.editUser , 'useredit buttonaction=save': click: this.updateUser ); , . updateUser: function(button) console.log('clicked

30、the Save button'); .);我們給this.control增加了一個(gè)選擇器調(diào)用,這次是useredit buttonaction=save. 這和第一個(gè)選擇器一樣,使用useredit 的xtype定位編輯用戶(hù)的窗口,然后找窗口里action為save的所有按鈕。在編輯用戶(hù)窗口里我們已經(jīng)給保存按鈕定義了action:save,可以很容易定位到這個(gè)按鈕。這樣當(dāng)點(diǎn)擊保存按鈕,就調(diào)用了updateUser這個(gè)方法。我們看到,我們的處理事件被正確地綁定到保存按鈕的單擊事件上了。然后我們來(lái)實(shí)現(xiàn)updateUser的真實(shí)邏輯。在這個(gè)方法里我們要從form里取得數(shù)據(jù),更新用戶(hù)信息,然

31、后保存會(huì)前面創(chuàng)建的用戶(hù)store??次覀儜?yīng)該怎么做:updateUser: function(button) var win = button.up('window'), form = win.down('form'), record = form.getRecord(), values = form.getValues(); record.set(values); win.close();我們來(lái)分析下。單擊事件提供了一個(gè)用戶(hù)點(diǎn)擊的按鈕的引用,但我們實(shí)際想得到的是包含數(shù)據(jù)的form和window。這這里我們?cè)俅问褂昧私M件查詢(xún),首先通過(guò)button.up(wind

32、ow)獲得編輯用戶(hù)窗口的引用,然后通過(guò)win.down(form)獲得form.然后我們獲取當(dāng)前加載的記錄,然后根據(jù)用戶(hù)的輸入更新記錄。最后我們關(guān)閉窗口,回到grid。現(xiàn)在再run程序,把姓名字段改成Ed Spencer然后單擊保存:8. 保存到服務(wù)器端-接下來(lái)我們讓程序可以和服務(wù)器端交互?,F(xiàn)在我們是把兩條用戶(hù)信息hard code到Users Store里的。所以首先替換成AJAX讀取數(shù)據(jù):Ext.define('AM.store.Users', extend: 'Ext.data.Store', model: 'AM.model.User',

33、 autoLoad: true, proxy: type: 'ajax', url: 'data/users.json', reader: type: 'json', root: 'users', successProperty: 'success' );這里我們以Proxy取代了data屬性。Proxies(代理)是Ext JS 4里從Store,Model加載和保存數(shù)據(jù)的方法。有AJAX,JSON-P和HTML5 localStorage以及其它的代理。這里我們用了一個(gè)簡(jiǎn)單的AJAX代理,告訴程序從data/users.json這個(gè)url去加載數(shù)據(jù)。同時(shí)我們給Proxy設(shè)置了Reader。Reader用來(lái)將服務(wù)器響應(yīng)解析成Store可以識(shí)別的格式。這里我們使用了JSON Reader,還指定了root和successProperty。最后我們創(chuàng)建一個(gè)data/user.json,然后加上之前的data: "success": true, "users": &

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論