精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Sencha Touch開發(fā)實例:記事本應(yīng)用(二)

移動開發(fā) 移動應(yīng)用
在本文中,我們將繼續(xù)學(xué)習(xí),如何完善這個記事應(yīng)用中的記事列表界面的功能,包括實現(xiàn)新建立和編輯記事的功能。

在《Sencha Touch開發(fā)實例:記事本應(yīng)用(一)》中, 我們介紹了移動跨平臺開發(fā)框架Sencha Touch的基本特性,并開始指導(dǎo)大家如何使用Sencha Touch開發(fā)一個簡單的記事應(yīng)用,其中講解了記事頁面列表的界面開發(fā)和代碼。在本文中,將繼續(xù)講解如何完善這個記事應(yīng)用中的記事列表界面的功能。在本文中,期望在學(xué)習(xí)完后,將會實現(xiàn)第一講中如下的界面框架,如下圖所示:

在Sencha Touch中創(chuàng)建數(shù)據(jù)模型

界面框架

下面我們分步來進(jìn)行開發(fā)。

在Sencha Touch中創(chuàng)建數(shù)據(jù)模型

在創(chuàng)建記事列表前,必須先創(chuàng)建記事的數(shù)據(jù)模型,這個可以使用Sencha Touch中的Ext.regModel()方法實現(xiàn),代碼如下:

  1. Ext.regModel('Note', { 
  2.     idProperty: 'id'
  3.     fields: [ 
  4.         { name: 'id', type: 'int' }, 
  5.         { name: 'date', type: 'date', dateFormat: 'c' }, 
  6.         { name: 'title', type: 'string' }, 
  7.         { name: 'narrative', type: 'string' } 
  8.     ], 
  9.     validations: [ 
  10.         { type: 'presence', field: 'id' }, 
  11.         { type: 'presence', field: 'title' } 
  12.     ] 
  13. }); 

 

在記事的數(shù)據(jù)模型中,這里定義了其名稱為”Note”,idPropoerty屬性則指定了數(shù)據(jù)模型的編號列,fileds屬性是個集合,其中指定了記事這個實體的四個屬性,并且用type指定了它們的類型。注意在數(shù)據(jù)模型中,validations則指定了校驗的規(guī)則,這里指定了id和title兩個屬性是必須填寫的,在稍后的新增記事的界面中,則會看到校驗規(guī)則是如何起作用的。

要注意的是,Sencha Touch中的數(shù)據(jù)模型,可以象Hibernate一樣,可以跟其他創(chuàng)建的更多的實體模型構(gòu)成關(guān)聯(lián)關(guān)系,比如一對一,一對多等,由于在本文中不存在這樣的關(guān)系,所以我們并沒有演示,但強(qiáng)烈建議讀者閱讀Sencha Touch的文檔中的相關(guān)部分。

使用HTML 5本地存儲機(jī)制保存用戶本地的數(shù)據(jù)

我們需要將數(shù)據(jù)存放起來,而Ext.regStore()可以很好地創(chuàng)建數(shù)據(jù)本地存儲,將數(shù)據(jù)保存起來,代碼如下:

  1. Ext.regStore('NotesStore', { 
  2.     model: 'Note'
  3.     sorters: [{ 
  4.         property: 'date'
  5.         direction: 'DESC' 
  6.     }], 
  7.     proxy: { 
  8.         type: 'localstorage'
  9.         id: 'notes-app-localstore' 
  10.     } 
  11. }); 

 

其中,我們通過model屬性,指定了要保存的實體為剛建立的Note,并使用sorters指定了存儲的數(shù)據(jù)中,要根據(jù)date日期字段進(jìn)行倒序排列。在proxy屬性中,實際上是生成了Ext.data.LocalStorageProxy的一個實例。Ext.data.LocalStorageProxy(可參考:http://dev.sencha.com/deploy/touch/docs/?class=Ext.data.LocalStorageProxy),實際上包裝了HTML5中新的本地存儲機(jī)制API,可以在客戶端的瀏覽器中保存數(shù)據(jù),當(dāng)然保存的數(shù)據(jù)不可能太復(fù)雜,Ext.data.LocalStorageProxy能負(fù)責(zé)對這些數(shù)據(jù)進(jìn)行序列化和反序列化。

建立記事列表

既然數(shù)據(jù)和存儲的模型都準(zhǔn)備好了,下面我們可以開始著手編寫記事列表的代碼了,代碼如下,很簡單:

  1. NotesApp.views.notesList = new Ext.List({ 
  2.     id: 'notesList'
  3.     store: 'NotesStore'
  4.     itemTpl: ' 
  5. <div class="list-item-title">{title}</div> 
  6. ' + 
  7.         ' 
  8. <div class="list-item-narrative">{narrative}</div> 
  9. }); 

 

在noteList列表中,我們使用的是Ext中的list列表控件,其中的store屬性指定了剛才建立好的NoteStore,而顯示模版屬性itemTpl,則分別用HTML代碼設(shè)定了title和narrative兩者的標(biāo)簽,其中都應(yīng)用了如下的CSS樣式:

  1. .list-item-title 
  2.     float:left; 
  3.     width:100%; 
  4.     font-size:90%; 
  5.     white-space: nowrap; 
  6.     overflow: hidden; 
  7.     text-overflow: ellipsis; 
  8. .list-item-narrative 
  9.     float:left; 
  10.     width:100%; 
  11.     color:#666666; 
  12.     font-size:80%; 
  13.     white-space: nowrap; 
  14.     overflow: hidden; 
  15.     text-overflow: ellipsis; 
  16. .x-item-selected .list-item-title 
  17.     color:#ffffff; 
  18. .x-item-selected .list-item-narrative 
  19.     color:#ffffff; 

 

現(xiàn)在,我們再把這個list添加到之前寫好的面板中去,如下代碼所示:

  1. NotesApp.views.notesListContainer = new Ext.Panel({  
  2.     id: 'notesListContainer',  
  3.     layout: 'fit',  
  4.     html: 'This is the notes list container',  
  5.     dockedItems: [NotesApp.views.notesListToolbar],  
  6.     items: [NotesApp.views.notesList]  
  7. });  

 

這里,把NotesApp.views.notesList加進(jìn)items項中了。我們?yōu)榱诉\行能看到效果,要先往數(shù)據(jù)模型中添加一條數(shù)據(jù),如下代碼:

  1. Ext.regStore('NotesStore', { 
  2.     model: 'Note'
  3.     sorters: [{ 
  4.         property: 'date'
  5.         direction: 'DESC' 
  6.     }], 
  7.     proxy: { 
  8.         type: 'localstorage'
  9.         id: 'notes-app-store' 
  10.     }, 
  11.     // TODO: 測試時用,測試后可以去除 
  12.     data: [ 
  13.         { id: 1, date: new Date(), title: 'Test Note', narrative: 'This is simply a test note' } 
  14.     ] 
  15. }); 

 

在模擬器中運行后,效果如下圖:

建立記事列表

模擬器運行效果圖

現(xiàn)在,我們還差兩個按鈕需要新增進(jìn)去,一個按鈕是新建記事的按鈕,另外一個是記事列表中,每一條后面的查看詳細(xì)情況的按鈕,如下圖:

建立記事列表

記事按鈕

下面是把“New”這個按鈕增加進(jìn)去的代碼:

  1. NotesApp.views.notesListToolbar = new Ext.Toolbar({ 
  2.     id: 'notesListToolbar'
  3.     title: 'My Notes'
  4.     layout: 'hbox'
  5.     items: [ 
  6.         { xtype: 'spacer' }, 
  7.         { 
  8.             id: 'newNoteButton'
  9.             text: 'New'
  10.             ui: 'action'
  11.             handler: function () { 
  12.                 // TODO: Create a blank note and make the note editor visible. 
  13.             } 
  14.         } 
  15.     ] 
  16. }); 

 

其中,注意在工具條Toolbar中,使用了hbox的布局,這樣可以是這個按鈕總是靠在右邊,而這個按鈕的處理事件,我們這里先不進(jìn)行處理,等待我們把新增記事的界面完成后,再編寫。

而對于記事本中每條記錄后的查看詳細(xì)的按鈕,可以通過新增加onItemDisclosure事件去實現(xiàn),代碼如下:

  1. NotesApp.views.notesList = new Ext.List({ 
  2.     id: 'notesList'
  3.     store: 'NotesStore'
  4.     itemTpl: ' 
  5. <div class="list-item-title">{title}</div> 
  6. ' + 
  7.         ' 
  8. <div class="list-item-narrative">{narrative}</div> 
  9. ', 
  10.     onItemDisclosure: function (record) { 
  11.         // TODO: Render the selected note in the note editor. 
  12.     } 
  13. }); 

 

在Sencha Touch的List控件中,每一行記錄都有onItemDisclosure事件(具體見http://dev.sencha.com/deploy/touch/docs/?class=Ext.List),在這個事件中,可以在獲得每一條在List中被點擊的記錄的具體情況,并進(jìn)行處理,在稍后的學(xué)習(xí)中,我們會在這個事件中編寫代碼進(jìn)行處理,以獲得被點擊記錄的情況,然后查看該記錄的具體情況。

接下來我們運行代碼,如下所示:

 

建立記事列表

帶按鈕的運行效果圖#p#

新建記事頁的編寫

下面我們編寫新建記事頁的頁面,在這個頁面中,可以完成記事的新增,刪除和修改,先來看下我們要設(shè)計的頁面如下:

新建記事頁的編寫

頁面設(shè)計圖

而我們希望實際運行的效果如下圖:

新建記事頁的編寫

運行效果圖

首先,我們還是把頁面的面板設(shè)計出來,代碼如下:

  1. NotesApp.views.noteEditor = new Ext.form.FormPanel({ 
  2.     id: 'noteEditor'
  3.     items: [ 
  4.         { 
  5.             xtype: 'textfield'
  6.             name: 'title'
  7.             label: 'Title'
  8.             required: true 
  9.         }, 
  10.         { 
  11.             xtype: 'textareafield'
  12.             name: 'narrative'
  13.             label: 'Narrative' 
  14.         } 
  15.     ] 
  16. }); 

 

其中,我們用到了Sencha Touch中的最基本的面板樣式FormPanel,其中增加了一個文本框和一個文本區(qū)域輸入框,并且在Title的required屬性中,指定了標(biāo)題是需要驗證的,用戶必須輸入內(nèi)容。

新建記事頁的編寫

輸入框效果圖

接下來,為了快速先能看到運行效果,我們可以先修改主界面的items中的界面指定,代碼如下:

  1. NotesApp.views.viewport = new Ext.Panel({ 
  2.     fullscreen: true
  3.     layout: 'card'
  4.     cardAnimation: 'slide'
  5. items: [NotesApp.views.noteEditor]  
  6. // 暫時注釋掉 [NotesApp.views.notesListContainer] 
  7. }); 

 

可以看到運行效果如下:

接下來,繼續(xù)往界面中增加工具條,首先是最上方的包含HOME和SAVE的工具條,代碼如下:

  1. NotesApp.views.noteEditorTopToolbar = new Ext.Toolbar({ 
  2.     title: 'Edit Note'
  3.     items: [ 
  4.         { 
  5.             text: 'Home'
  6.             ui: 'back'
  7.             handler: function () { 
  8.                 // TODO: Transition to the notes list view. 
  9.             } 
  10.         }, 
  11.         { xtype: 'spacer' }, 
  12.         { 
  13.             text: 'Save'
  14.             ui: 'action'
  15.             handler: function () { 
  16.                 // TODO: Save current note. 
  17.             } 
  18.         } 
  19.     ] 
  20. }); 

 

其中,對于BACK按鈕,指定了ui:back的樣式,對于保存SAVE按鈕,使用了ui:action的樣式,這些都是Sencha Touch本身固定的樣式,效果如下:

新建記事頁的編寫

導(dǎo)航欄

接下來,我們設(shè)計頁面下部,用于給用戶刪除記事的圖標(biāo),代碼如下:

  1. NotesApp.views.noteEditorBottomToolbar = new Ext.Toolbar({  
  2.     dock: 'bottom',  
  3.     items: [  
  4.         { xtype: 'spacer' },  
  5.         {  
  6.             iconCls: 'trash',  
  7.             iconMask: true,  
  8.             handler: function () {  
  9.                 // TODO: Delete current note.  
  10.             }  
  11.         }  
  12.     ]  
  13. });  

 

在這里,要注意我們是如何把垃圾站的圖標(biāo)放在最底部的,這里使用的是dock屬性中指定為bottom,并請注意這里是如何把垃圾站的圖標(biāo)放到按鈕中去的(iconCls屬性指定了使用默認(rèn)的垃圾站圖標(biāo),而iconMask則指定了圖標(biāo)是在按鈕中)。效果如下圖:

新建記事頁的編寫

垃圾站圖標(biāo)

現(xiàn)在我們看下把上部及下部的工具條都添加后的代碼,如下所示:

  1. NotesApp.views.noteEditor = new Ext.form.FormPanel({ 
  2.     id: 'noteEditor'
  3.     items: [ 
  4.         { 
  5.             xtype: 'textfield'
  6.             name: 'title'
  7.             label: 'Title'
  8.             required: true 
  9.         }, 
  10.         { 
  11.             xtype: 'textareafield'
  12.             name: 'narrative'
  13.             label: 'Narrative' 
  14.         } 
  15.     ], 
  16.     dockedItems: [ 
  17.             NotesApp.views.noteEditorTopToolbar, 
  18.             NotesApp.views.noteEditorBottomToolbar 
  19.         ] 
  20. }); 

 

運行代碼后,可以看到如下的效果:

新建記事頁的編寫

運行效果圖

好了,現(xiàn)在我們可以開始學(xué)習(xí),如何從記事的列表中,點查看每個記事詳細(xì)的按鈕,而切換到查看具體的記事,以及如何點新增按鈕,而切換到新增記事的頁面#p#

Sencha Touch中的頁面切換

我們先來看下,如何當(dāng)用戶點“New”按鈕時,Sencha Touch如何從記事列表頁面中切換到新建記事的頁面中。代碼如下:

  1. NotesApp.views.notesListToolbar = new Ext.Toolbar({ 
  2.     id: 'notesListToolbar'
  3.     title: 'My Notes'
  4.     layout: 'hbox'
  5.     items: [ 
  6.         { xtype: 'spacer' }, 
  7.         { 
  8.             id: 'newNoteButton'
  9.             text: 'New'
  10.             ui: 'action'
  11.             handler: function () { 
  12.  
  13.                 var now = new Date(); 
  14.                 var noteId = now.getTime(); 
  15.                 var note = Ext.ModelMgr.create( 
  16.                     { id: noteId, date: now, title: '', narrative: '' }, 
  17.                     'Note' 
  18.                 ); 
  19.  
  20.                 NotesApp.views.noteEditor.load(note); 
  21.                 NotesApp.views.viewport.setActiveItem('noteEditor', {type: 'slide', direction: 'left'}); 
  22.             } 
  23.         } 
  24.     ] 
  25. }); 

 

請留意這里,我們補(bǔ)全了之前的新建按鈕中的handler事件中的代碼,下面逐一分析,首先先看這段代碼:

  1. var now = new Date(); 
  2. var noteId = now.getTime(); 
  3. var note = Ext.ModelMgr.create( 
  4.     { id: noteId, date: now, title: '', narrative: '' }, 
  5.     'Note' 
  6. ); 

 

這里首先建立了一個空的note記事對象,其中該對象的date字段使用了當(dāng)前的時間填充。

接下來,充分利用了Sencha Touch中的formpanel的load方法,該方法可以直接把用戶在前端界面輸入的內(nèi)容包裝成實體對象的對應(yīng)屬性,這里用:

NotesApp.views.noteEditor.load(note)。最后,我們要設(shè)置新增頁面為可見,代碼為:

  1. NotesApp.views.viewport.setActiveItem('noteEditor', {type: 'slide', direction: 'left'}); 

通過NotesApp.views.viewport.setActiveItem方法,設(shè)置了noteEditor(新增記事頁面)為活動頁面,并且設(shè)置了出現(xiàn)的效果為slide滑動,方向為向左移動出現(xiàn)。

要記得,我們之前測試時,取消了主面板中的items中的新增記事頁面,由于現(xiàn)在我們設(shè)置了轉(zhuǎn)換,所以要重新加上,代碼如下:

  1. NotesApp.views.viewport = new Ext.Panel({ 
  2.     fullscreen: true
  3.     layout: 'card'
  4.     cardAnimation: 'slide'
  5.     items: [ 
  6.         NotesApp.views.notesListContainer, 
  7.         NotesApp.views.noteEditor 
  8.     ] 
  9. }); 

 

運行后,當(dāng)點NEW按鈕后,可以跳轉(zhuǎn)到新增記事頁面,如下圖:

Sencha Touch中的頁面切換

界面跳轉(zhuǎn)#p#

驗證用戶的輸入

接下來,我們來看下,保存記事前,如何做用戶輸入的校驗。在當(dāng)用戶按保存按鈕時,其邏輯如下:

1、如果用戶沒輸入標(biāo)題,則提示用戶輸入。

2、如果是新的一條記事,將會將其放到cache中,如果已經(jīng)存在則更新。

3、最后更新記事列表。

在更新保存前,必須先進(jìn)行校驗,所以我們修改之前的Notes實體的檢驗規(guī)則,如下代碼:

  1. Ext.regModel('Note', { 
  2.     idProperty: 'id', 
  3.     fields: [ 
  4.         { name: 'id', type: 'int' }, 
  5.         { name: 'date', type: 'date', dateFormat: 'c' }, 
  6.         { name: 'title', type: 'string' }, 
  7.         { name: 'narrative', type: 'string' } 
  8.     ], 
  9.     validations: [ 
  10.         { type: 'presence', field: 'id' }, 
  11.         { type: 'presence', field: 'title', message: 'Please enter a title for this note.' } 
  12.     ] 
  13. }); 

 

這里,在title中,增加了message屬性,即當(dāng)用戶沒輸入內(nèi)容時顯示提示的內(nèi)容。接下來,我們完善保存的代碼,如下:

  1. NotesApp.views.noteEditorTopToolbar = new Ext.Toolbar({ 
  2.     title: 'Edit Note'
  3.     items: [ 
  4.         { 
  5.             text: 'Home'
  6.             ui: 'back'
  7.             handler: function () { 
  8.                 NotesApp.views.viewport.setActiveItem('notesListContainer', { type: 'slide', direction: 'right' }); 
  9.             } 
  10.         }, 
  11.         { xtype: 'spacer' }, 
  12.         { 
  13.             text: 'Save'
  14.             ui: 'action'
  15.             handler: function () { 
  16.  
  17.                 var noteEditor = NotesApp.views.noteEditor; 
  18.  
  19.                 var currentNote = noteEditor.getRecord(); 
  20.              
  21.                 noteEditor.updateRecord(currentNote); 
  22.  
  23.                 var errors = currentNote.validate(); 
  24.                 if (!errors.isValid()) { 
  25.                     Ext.Msg.alert('Wait!', errors.getByField('title')[0].message, Ext.emptyFn); 
  26.                     return
  27.                 } 
  28.  
  29.                 var notesList = NotesApp.views.notesList; 
  30.                 var notesStore = notesList.getStore(); 
  31.  
  32.                 if (notesStore.findRecord('id', currentNote.data.id) === null) { 
  33.                     notesStore.add(currentNote); 
  34.                 } 
  35.  
  36.                 notesStore.sync(); 
  37.   notesStore.sort([{ property: 'date', direction: 'DESC'}]); 
  38.  
  39.                 notesList.refresh(); 
  40.  
  41.                 NotesApp.views.viewport.setActiveItem('notesListContainer', { type: 'slide', direction: 'right' }); 
  42.  
  43.             } 
  44.         } 
  45.     ] 
  46. }); 

 

下面分段講解代碼。首先在SAVE按鈕的handler事件中,用變量noteEditor獲得了當(dāng)前新增界面NotesApp.views.noteEditor的實例,接著用getRecord()方法獲得了用戶在前端輸入,已經(jīng)裝載封裝好的Note對象,再使用updateRecord()方法,將需要更新的Note實體對象進(jìn)行更新。

在調(diào)用currentNote.validate()的驗證方法時后,可以用!errors.isValid()中判斷是否校驗成功或失敗,當(dāng)校驗失敗后,使用Ext.Msg.alert方法顯示用戶沒填寫記事的標(biāo)題。

在通過校驗后,使用notesList.getStore()獲得當(dāng)前瀏覽器中本地存儲的數(shù)據(jù)集合,并且我們判斷記錄是否存在,如果不存在,則新增,否則更新,這個很容易實現(xiàn),代碼如下:

  1. var notesStore = notesList.getStore(); 
  2. if (notesStore.findRecord('id', currentNote.data.id) === null) { 
  3.     notesStore.add(currentNote); 

 

這里通過判斷本地存儲中是否有currentNote.data.id,從而得知是否為新增記錄,如果沒有,則調(diào)用add方法新增。

最后,如果是更新記錄的話,調(diào)用sync方法將記錄持續(xù)化保存到本地存儲集中,再通過refresh刷新方法,刷新當(dāng)前記事列表,并將頁面切換到記事列表中,如下代碼:

  1. notesList.refresh(); 
  2.  
  3. otesApp.views.viewport.setActiveItem('notesListContainer', { type: 'slide', direction: 'right' }); 

 

這里同樣通過setActiveItem方法,切換到notesListContainer的記事列表界面。

同時,我們看下HOME按鈕的編寫,也是很簡單,如下:

  1.     text: 'Home'
  2.     ui: 'back'
  3.     handler: function () { 
  4.         NotesApp.views.viewport.setActiveItem('notesListContainer', { type: 'slide', direction: 'right' });'s next 
  5.     } 

 

#p#

編輯記事

我們再來看下如何編輯記事。在記事列表中,當(dāng)用戶點每一條記事后的小圖標(biāo),就會直接轉(zhuǎn)換到編輯記事的頁面,顯示當(dāng)前選擇記事的內(nèi)容,界面如下圖:

處理記事

記事列表界面顯示

這里,我們補(bǔ)充完善之前的onItemDisclosure事件代碼即可,如下:

  1. NotesApp.views.notesList = new Ext.List({ 
  2.     id: 'notesList'
  3.     store: 'NotesStore'
  4.     onItemDisclosure: function (record) { 
  5.         var selectedNote = record; 
  6.         NotesApp.views.noteEditor.load(selectedNote); 
  7.         NotesApp.views.viewport.setActiveItem('noteEditor', { type: 'slide', direction: 'left' }); 
  8.     }, 
  9.     itemTpl: ' 
  10. <div class="list-item-title">{title}</div>' + 
  11.         '<div class="list-item-narrative">{narrative}</div>'
  12.     listeners: { 
  13.         'render'function (thisComponent) { 
  14.             thisComponent.getStore().load(); 
  15.         } 
  16.     } 
  17. }); 

 

還記得么?onItemDisclosure事件發(fā)生在LIST列表中當(dāng)用戶點每一項時,這里,我們用selectedNote變量獲得了當(dāng)前的記錄,然后利用NotesApp.views.noteEditor.load方法,就可以在新增記事的頁面中,把記錄重新加載顯示出來,十分方便。

刪除記事

刪除某一個記事時,用戶點頁面底部的垃圾桶圖標(biāo)即可,代碼如下:

  1. NotesApp.views.noteEditorBottomToolbar = new Ext.Toolbar({ 
  2.     dock: 'bottom'
  3.     items: [ 
  4.         { xtype: 'spacer' }, 
  5.         { 
  6.             iconCls: 'trash'
  7.             iconMask: true
  8.             handler: function () { 
  9.  
  10.                 var currentNote = NotesApp.views.noteEditor.getRecord(); 
  11.                 var notesList = NotesApp.views.notesList; 
  12.                 var notesStore = notesList.getStore(); 
  13.  
  14.                 if (notesStore.findRecord('id', currentNote.data.id)) { 
  15.                     notesStore.remove(currentNote); 
  16.                 } 
  17.  
  18.                 notesStore.sync(); 
  19.  
  20.                 notesList.refresh(); 
  21.                 NotesApp.views.viewport.setActiveItem('notesListContainer', { type: 'slide', direction: 'right' }); 
  22.             } 
  23.         } 
  24.     ] 
  25. }); 

 

同樣,通過currentNote變量獲得要刪除的記錄實例,然后用notesStore獲得當(dāng)前的本地存儲集合,再通過findRecord方法去判斷是否存在該記錄,如果存在該記錄,則調(diào)用remove方法進(jìn)行刪除,同樣,跟保存記事的代碼一樣,要記得調(diào)用sync方法同步及調(diào)用refresh方法刷新記事列表。#p#

將記事進(jìn)行分組

我們這個教程中要做的最后一個例子,是按記事的日期進(jìn)行分類排序,代碼如下:

  1. NotesApp.views.notesList = new Ext.List({ 
  2.     id: 'notesList'
  3.     store: 'NotesStore'
  4.     grouped: true
  5.     emptyText: '<div style="margin: 5px;">No notes cached.</div>'
  6.     onItemDisclosure: function (record) { 
  7.         var selectedNote = record; 
  8.         NotesApp.views.noteEditor.load(selectedNote); 
  9.         NotesApp.views.viewport.setActiveItem('noteEditor', { type: 'slide', direction: 'left' }); 
  10.     }, 
  11.     itemTpl: '<div class="list-item-title">{title}</div>' + 
  12.         '<div class="list-item-narrative">{narrative}</div>'
  13.     listeners: { 
  14.         'render'function (thisComponent) { 
  15.             thisComponent.getStore().load(); 
  16.         } 
  17.     } 
  18. }); 

 

這里,設(shè)定了grouped的屬性為true,表明列表的數(shù)據(jù)要進(jìn)行分組處理,接下來,由于要根據(jù)日期進(jìn)行分組,我們重寫getGroupsString方法,如下代碼:

  1. Ext.regStore('NotesStore', { 
  2.     model: 'Note'
  3.     sorters: [{ 
  4.         property: 'date'
  5.         direction: 'DESC' 
  6.     }], 
  7.     proxy: { 
  8.         type: 'localstorage'
  9.         id: 'notes-app-store' 
  10.     }, 
  11.     getGroupString: function (record) { 
  12.         if (record && record.data.date) { 
  13.             return record.get('date').toDateString(); 
  14.         } else { 
  15.             return ''
  16.         } 
  17.     } 
  18. }); 

 

在getGroupsString中,返回的是根據(jù)什么字段去進(jìn)行分組,這里將每條記錄的日期轉(zhuǎn)化為字符串返回,因為我們希望每個分組的標(biāo)題為日期。運行后效果如圖:

處理記事

運行效果圖

本教程的完整代碼下載:

http://miamicoder.com/wp-content/uploads/2011/06/Notes-App-v1.0.zip

責(zé)任編輯:佚名 來源: it168
相關(guān)推薦

2011-07-26 10:21:25

Sencha Touc

2011-09-02 15:18:49

Sencha Touc

2011-07-26 09:58:24

2023-09-21 11:30:11

2011-09-02 16:42:51

Sencha ToucWeb應(yīng)用

2011-07-25 16:21:22

Sencha touc

2012-01-10 14:10:26

Sencha Touc

2011-08-15 09:51:45

Sencha TouciPad

2011-09-05 10:49:14

Sencha ToucjQuery MobiHTML5

2009-09-03 13:08:43

C#調(diào)用記事本

2011-09-05 11:23:26

EclipseSencha Touc框架

2010-11-22 10:31:17

Sencha touc

2011-07-26 09:41:50

Sencha Touc特性HTML 5

2011-09-01 10:09:04

2011-07-25 15:55:21

Sencha ToucHtml 5

2024-01-10 09:50:58

AI 寫作功能CoWriterChatGPT

2011-12-20 15:59:28

2011-09-05 10:27:02

Sencha Touc手機(jī)應(yīng)用Android

2011-09-05 14:17:54

Sencha ToucMVC

2011-09-05 11:27:17

Sencha Touc框架HTML5
點贊
收藏

51CTO技術(shù)棧公眾號

国产一区二区丝袜高跟鞋图片| 经典三级一区二区| 国产精品色婷婷在线观看| 不卡视频在线看| 欧美成人国产va精品日本一级| 国产成人在线免费看| 岛国片在线免费观看| 免费在线小视频| 高清在线观看日韩| 精品国内亚洲在观看18黄| 又色又爽又高潮免费视频国产| 天天操天天干天天操| 欧美午夜久久| 日韩欧美国产电影| 激情图片qvod| 99久久国产免费| 欧美r级电影| 欧美日韩精品电影| 亚洲一区三区| 国产又粗又大又黄| 天天综合亚洲| 91精品国产高清一区二区三区蜜臀| 亚洲国产另类久久久精品极度| 蜜臀尤物一区二区三区直播| 国产真实有声精品录音| 在线观看日韩高清av| 日本视频一区在线观看| 欧美日韩 一区二区三区| 午夜精品视频| 精品久久久久一区| 国产精品久久久久久久乖乖| 成人午夜精品福利免费| 一本久久知道综合久久| 国产视频精品xxxx| 亚洲三级视频网站| 欧美成年黄网站色视频| 99精品在线观看| 日韩国产精品一区| 国产精品亚洲a| yw193.com尤物在线| 日韩电影网1区2区| 精品国内自产拍在线观看| 成人免费无遮挡无码黄漫视频| 另类图片综合电影| 中文字幕一区二区三区视频| 97久草视频| 日韩 欧美 综合| 欧美午夜精彩| 日韩一级片网站| 国产中文字幕视频在线观看| 曰本三级在线| 久久嫩草精品久久久久| 国产精品 欧美在线| fc2ppv在线播放| 国产毛片久久久| 欧美亚洲动漫制服丝袜| 免费看黄色a级片| 桃花色综合影院| 麻豆国产精品777777在线| 欧美另类高清videos| 亚洲天堂网一区二区| 丁香久久综合| 亚洲不卡一区二区三区| 亚洲精品一品区二品区三品区| 精品推荐蜜桃传媒| 国产成人免费视频 | 三级在线播放| 免费不卡在线观看| 高清欧美电影在线| 九九热久久免费视频| 久久社区一区| 欧美成aaa人片免费看| 久久99久久久| 欧美mv日韩| 欧美成人精品在线| 麻豆一区二区三区精品视频| 不卡在线一区二区| 另类色图亚洲色图| аⅴ天堂中文在线网| 成人h动漫免费观看网站| 欧美日韩美女一区二区| www.五月天色| 日本一区二区三区中文字幕 | 波多野结衣与黑人| 国产在线高清| 国产精品久久二区二区| 成年丰满熟妇午夜免费视频| 国产乱码午夜在线视频| 亚洲精品高清视频在线观看| 五月天亚洲综合小说网| 欧美扣逼视频| 26uuu国产电影一区二区| 国产乱码精品一区二区三区卡| av网站在线观看免费| 日本人妖一区二区| 日韩av免费在线| 波多野结衣国产| 亚洲韩日在线| 高清在线视频日韩欧美| 国产成人无码专区| 视频一区视频二区在线观看| 2019日本中文字幕| 久久久久人妻一区精品色| 欧美精品一二| 亚洲欧美日韩爽爽影院| 一区二区三区免费在线观看视频| 成人影视亚洲图片在线| 性欧美激情精品| 日韩精品人妻中文字幕| 亚洲私拍自拍| 久久免费视频网站| 中文字幕视频免费观看| 青草国产精品久久久久久| 91最新在线免费观看| 国产草草影院ccyycom| 久久久噜噜噜久久中文字幕色伊伊 | 亚洲激情免费观看| 中文字幕99页| 国产毛片久久久| 久久精品国产亚洲精品2020| 国产又大又黄视频| 日韩主播视频在线| 国产日韩精品推荐| 色视频免费在线观看| 亚洲欧美另类在线| 超级碰在线观看| 国产日本久久| 日韩欧美专区在线| 任我爽在线视频| 久久资源在线| 精选一区二区三区四区五区| 男操女在线观看| 亚洲电影第三页| 黄www在线观看| 久久天堂av| 91麻豆精品国产综合久久久久久| a级大片免费看| 色橹橹欧美在线观看视频高清| 亚洲一区二区久久久| 国产一区第一页| 天堂一区二区在线| 欧美久久在线| free性欧美hd另类精品| 精品久久久中文| 美女网站色免费| 在线精品国产亚洲| 亚洲无av在线中文字幕| 依依成人综合网| 26uuu国产在线精品一区二区| 国产中文字幕视频在线观看| 欧美aaaaaaaa牛牛影院| 中文字幕久久久av一区| 免费看一级一片| 国产a视频精品免费观看| 三年中文高清在线观看第6集 | 一区二区欧美在线观看| 成年人网站免费视频| 久久夜夜久久| 日韩在线观看av| 欧美三级一区二区三区| 99久久国产综合精品女不卡 | 中文字幕亚洲综合久久五月天色无吗''| 欧美激情视频在线| 欧美一级做a爰片免费视频| 国产成人综合在线| r级无码视频在线观看| 国产黄色精品| 久久伊人精品视频| 免费观看的毛片| 亚洲同性gay激情无套| 欧美日韩在线中文| 日韩88av| 国产97色在线| 国产在线看片| 欧美四级电影网| 极品色av影院| 成人三级伦理片| 特级黄色录像片| av一级亚洲| 日本一区二区三区四区视频| fc2在线中文字幕| 欧美一三区三区四区免费在线看| 久久久久久久久久久久久久免费看 | 精品无人区无码乱码毛片国产 | 欧美日韩蜜桃| 欧美区高清在线| 一区在线不卡| 亚洲人成网站免费播放| 日韩免费黄色片| 国产拍欧美日韩视频二区| 国产一区二区网| 日韩精品看片| 国外成人免费视频| 四虎在线精品| 欧美在线视频观看免费网站| 秋霞欧美在线观看| 欧美亚洲禁片免费| 久久久久人妻一区精品色欧美| 国产日韩欧美麻豆| 北条麻妃在线视频| 欧美激情日韩| 性欧美videosex高清少妇| www.神马久久| 91久久久亚洲精品| 97高清免费视频| 日韩在线一区二区三区四区| 在线看一区二区| 久久久久久久蜜桃| 国产精品久久久久精k8| 男女一区二区三区| 很黄很黄激情成人| 亚洲va久久久噜噜噜久久狠狠| 精品国产一区二| 欧美成人在线免费| 国产一级片在线播放| 欧美成人vr18sexvr| 亚洲视频在线观看免费视频| 国产精品免费网站在线观看| 无限资源日本好片| 99视频精品免费观看| 正在播放一区| 中文字幕一区二区三区中文字幕 | 日本一区二区三区四区在线观看 | 久久草.com| 蜜桃视频www网站在线观看| 久久久av网站| 成人午夜影视| 亚洲精品自拍第一页| 亚洲精品国产一区二| 天天综合色天天| 黄色一级视频免费| 国产精品成人免费精品自在线观看| 国产激情在线免费观看| 久久亚洲欧美| 国产69精品久久久久久久| 久久久久久久久国产一区| 国产在线a不卡| 成人性生活视频| 欧美裸体xxxx极品少妇| 黄色精品免费看| 久久精品国产亚洲精品2020| 一区二区高清不卡| 日韩欧美国产精品一区| 国产亲伦免费视频播放| 欧美午夜精品一区二区三区| 波多野结衣毛片| 色婷婷综合久久久中文字幕| 日韩在线一卡二卡| 国产精品久久久一本精品| 四季av中文字幕| 日本一二三不卡| 伊人成人免费视频| 国内精品自线一区二区三区视频| 精品久久久久久无码中文野结衣| 亚洲午夜精品一区二区国产| 一级全黄肉体裸体全过程| 久久久久久久久久久久久久| 天堂av免费看| 午夜精品偷拍| 国产美女主播在线播放| 99综合视频| 欧美精品第三页| 欧美aaaaa成人免费观看视频| 一起操在线视频| 黄色欧美成人| a级黄色一级片| 日韩中文字幕不卡| 中文字幕视频三区| 国产99久久久国产精品潘金| 亚洲制服丝袜在线播放| 狠狠色狠狠色综合| 伊人影院在线观看视频| 蜜臀99久久精品久久久久久软件| 亚洲精品久久久久久宅男| 国产毛片精品国产一区二区三区| 激情六月丁香婷婷| 极品少妇一区二区三区| 中文字幕一区二区三区四区五区六区 | 精品女同一区二区| 五月天婷婷激情网| 337p亚洲精品色噜噜噜| www.久久伊人| 91麻豆精品国产91久久久资源速度 | 在线不卡一区二区| www欧美在线| 精品视频一区 二区 三区| 少妇一级淫片免费放中国| 欧亚洲嫩模精品一区三区| 国产色综合视频| 日韩成人在线免费观看| 色欧美激情视频在线| 欧美精品xxx| 97caopron在线视频| 97av在线播放| **欧美日韩在线| 免费观看成人高| 日韩精品福利一区二区三区| 手机在线观看国产精品| 亚洲国产清纯| 182午夜在线观看| 美腿丝袜亚洲综合| 国产精品嫩草av| 亚洲日本青草视频在线怡红院| 中文字幕亚洲精品一区| 日韩视频永久免费| 国产人成在线观看| 亚洲图片欧美日产| 2018av在线| 96精品视频在线| 国产精品中文| 日韩一区免费观看| 久久中文字幕二区| www.爱色av.com| 国产成人精品综合在线观看| 一级在线观看视频| 欧美日韩性视频在线| 亚洲大片免费观看| 精品人在线二区三区| 午夜伦理在线| 国产精品91免费在线| 欧美爱爱网站| 久草免费福利在线| 国产精品综合av一区二区国产馆| www..com.cn蕾丝视频在线观看免费版 | 欧美日韩视频在线| 日本xxxx人| 国模极品一区二区三区| 午夜久久av| 精品国产福利| 欧美激情四色| 超碰在线超碰在线| 综合亚洲深深色噜噜狠狠网站| 少妇久久久久久被弄高潮| 香蕉av福利精品导航| 亚洲av少妇一区二区在线观看| 久久天天躁狠狠躁夜夜躁 | 国产日韩亚洲| 日本美女高潮视频| 久久五月婷婷丁香社区| av资源免费观看| 日韩国产高清视频在线| 日韩电影免费看| 久久资源亚洲| 丝袜亚洲另类欧美综合| 国产真实乱人偷精品人妻| 色综合天天在线| 国产原创av在线| 国产精品精品国产| 亚洲视频精选| 激情五月六月婷婷| 粉嫩一区二区三区性色av| 久久国产在线观看| 精品国产三级a在线观看| 电影av一区| 国产精品亚洲自拍| 波多野结衣欧美| cao在线观看| www国产成人免费观看视频 深夜成人网| 久久久久久欧美精品se一二三四| 亚洲成人在线网| 麻豆传媒在线观看| 成人av在线天堂| 色狼人综合干| 国产福利一区视频| 国产精品色哟哟网站| 国产乱码精品一区二区| 日韩高清免费在线| 天天免费亚洲黑人免费| 国产精华一区| 图片区亚洲欧美小说区| 国产999免费视频| 亚洲电影一区二区三区| 九色蝌蚪在线| 成人xvideos免费视频| 欧美精品黄色| 国产手机在线观看| 欧美猛男超大videosgay| 欧美性猛片xxxxx免费中国| 国产免费亚洲高清| 欧美天堂亚洲电影院在线观看| 精品一区二区视频在线观看| 91福利资源站| 九一在线视频| 91日韩在线视频| 一区二区三区导航| 中文字幕无码日韩专区免费| 欧美精品一区二区三区蜜桃视频| 99re66热这里只有精品4| 粉嫩av一区二区三区天美传媒| 久久综合久久久久88| 国产女人高潮毛片| 欧美中文在线观看国产| 一区二区三区毛片免费| 国产精品jizz| 欧美性猛交xxxx乱大交蜜桃 | 国产精品1区二区.| 黑人精品无码一区二区三区AV| 亚洲国产高清自拍| 成人四虎影院| 麻豆tv在线播放|