精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

午夜影院在线播放| 国产三级按摩推拿按摩| 亚洲三级av| 一区二区三区视频在线观看 | 最新国产露脸在线观看| 国产成人综合亚洲91猫咪| 久久久午夜视频| 污污免费在线观看| 亚洲三级欧美| 最好看的中文字幕久久| 懂色一区二区三区av片| 久久精品国产亚洲av无码娇色| 欧美黑人做爰爽爽爽| 欧美日本一道本| aa在线免费观看| h网站久久久| 国产三级精品三级| 高清日韩一区| 国产日韩免费视频| 毛片一区二区三区| 国产91色在线播放| 日韩成人免费在线观看| 91精品秘密在线观看| 亚洲天堂日韩电影| 日韩 中文字幕| 亚洲一区二区三区在线免费| 欧美色中文字幕| 波多野结衣家庭教师在线| 91精品久久久久久粉嫩| 中文字幕乱码亚洲精品一区| 蜜桃臀一区二区三区| 国产 欧美 精品| 国产九九视频一区二区三区| 国产精品欧美一区二区| 国产无套丰满白嫩对白| 亚洲伦伦在线| 久久久久中文字幕2018| 国产精品成人免费观看| 亚州av乱码久久精品蜜桃| 一区二区三区www| 久久av无码精品人妻系列试探| 国产精品久久久久av蜜臀| 91精品婷婷国产综合久久性色| 色播五月综合网| 91亚洲视频| 欧美在线一区二区三区| 成人一区二区三| 99re66热这里只有精品4| 日韩欧美在线观看视频| 久久久久久久久久久久久国产精品| 国产精品yjizz视频网| 亚洲成人激情自拍| 无码精品a∨在线观看中文| 国产精品国精产品一二| 午夜久久久久久电影| 又粗又黑又大的吊av| 都市激情亚洲一区| 欧美在线观看一区二区| 91视频免费版污| 国产在视频一区二区三区吞精| 欧美又粗又大又爽| 亚洲欧美日韩网站| 中文字幕一区二区三区日韩精品| 亚洲成色777777女色窝| 精品夜夜澡人妻无码av| 色综合中文网| 日韩在线视频网| 三级影片在线看| 亚洲欧美亚洲| 98视频在线噜噜噜国产| 男人天堂av在线播放| 久久丁香综合五月国产三级网站| 成人av在线网址| 亚洲大尺度视频| 久久亚洲一区二区三区明星换脸| 日韩免费电影一区二区| 黄在线免费观看| 亚洲成人av一区二区三区| 国产最新免费视频| 久久天堂av| 日韩一区二区三区免费看 | 久久影视精品| 欧美成人r级一区二区三区| 你懂的在线观看网站| 国内精品久久久久久99蜜桃| 久久久国产精品视频| 日操夜操天天操| 日本欧美一区二区三区乱码| 成人激情视频网| 天堂中文在线观看视频| 国产精品无人区| 大西瓜av在线| 岛国毛片av在线| √天堂中文官网8在线| 国产一区二区三区四区二区| 久久精品国产96久久久香蕉| 久久综合色综合| 日韩精品91亚洲二区在线观看| 亚洲qvod图片区电影| 日韩在线免费看| 亚洲欧美日韩久久精品| 黄在线观看网站| 国产麻豆精品| 亚洲另类欧美自拍| 五月天丁香激情| 日韩一区精品字幕| 粉嫩精品一区二区三区在线观看| 国产在线视频网址| 国产高清一区| 国产亚洲视频在线| 久久久91视频| 日本欧美在线看| 日本视频在线播放| 精品国产户外野外| 国产成人美女视频| 一区二区三区韩国免费中文网站| 欧美成人午夜剧场免费观看| 日本中文字幕在线观看视频| 成人毛片在线观看| 2021国产视频| 日韩久久99| 亚洲天堂av在线免费| 日韩欧美大片在线观看| 国产福利视频一区二区三区| 天堂av一区二区| 欧美成人a交片免费看| 国产麻豆精品久久一二三| 精品欧美日韩在线| 手机在线免费av| 在线播放国产精品二区一二区四区| 丰满圆润老女人hd| 亚洲高清毛片| 成人在线观看av| 中文在线观看免费| 91麻豆精品国产91久久久| 亚洲一级片在线播放| 日日夜夜精品视频天天综合网| 国产欧美日韩一区二区三区| 青青青国内视频在线观看软件| 91精品国产综合久久小美女| 羞羞在线观看视频| 国模一区二区三区白浆| 中国人体摄影一区二区三区| 日本午夜免费一区二区| 色婷婷综合久久久久| 亚洲一区二区色| 日本一区二区三级电影在线观看 | 亚洲人体大胆视频| 国产91色在线|亚洲| 国模雨婷捆绑高清在线| 亚洲国产精品福利| 精品成人免费视频| 91亚洲精品一区二区乱码| 国产白丝袜美女久久久久| 丝袜连裤袜欧美激情日韩| 欧美一区二区色| 美丽的姑娘在线观看免费动漫| 欧美性猛交xxxx免费看漫画| 法国空姐电影在线观看| 人人狠狠综合久久亚洲| 伊人久久av导航| 精品国产一区二区三区性色av| 欧美巨猛xxxx猛交黑人97人| 刘玥91精选国产在线观看| 精品高清一区二区三区| 久久精品无码一区| 精品一区精品二区高清| 国产1区2区3区中文字幕| 精品综合久久88少妇激情| 日韩av电影中文字幕| 69视频在线| 日韩欧美国产一区二区三区 | 精品国产91亚洲一区二区三区www| 91黄页在线观看| 亚洲日韩欧美视频一区| 亚洲一级特黄毛片| 亚洲国产成人精品视频| 国精产品一区一区三区免费视频| 日本不卡视频在线观看| 中文字幕免费高| 国产日韩三级| 国产精品入口福利| 欧美性爽视频| 亚洲一级黄色片| www.国产黄色| 色哟哟亚洲精品| jizz亚洲少妇| 久久久久久久av麻豆果冻| 久国产精品视频| 香蕉精品999视频一区二区| 亚洲精品一卡二卡三卡四卡| 亚洲网一区二区三区| 青青久久av北条麻妃黑人| 黄色片免费在线观看| 精品偷拍各种wc美女嘘嘘| 亚洲天堂视频在线| 亚洲va欧美va国产va天堂影院| 91激情视频在线观看| 国产成人精品一区二区三区网站观看 | 国产精品爽黄69天堂a| 久久不射影院| 最新日韩中文字幕| 三级在线视频| 日韩欧美一卡二卡| 欧美视频xxxx| 性欧美疯狂xxxxbbbb| 亚洲精品自拍视频在线观看| 91免费精品国自产拍在线不卡| www.久久久久久久久久久| 小嫩嫩精品导航| 日本手机在线视频| 天天av综合| 天堂√在线观看一区二区| 日本韩国欧美超级黄在线观看| 亚洲va欧美va国产综合久久| yw.尤物在线精品视频| 欧美一级电影在线| 久草在线新免费首页资源站| 精品久久久av| 亚洲欧美视频一区二区| 亚洲人成网站777色婷婷| 日本高清视频免费看| 欧美一区二区视频在线观看2020 | 精品一区二区三区免费视频| 成人在线看视频| 亚洲三级电影在线观看| 一二三四中文字幕| 欧美a级片网站| 最新av在线免费观看| 日韩国产一区| 日韩国产精品一区二区三区| 国产精品手机在线播放| 免费久久99精品国产自| 少妇精品导航| 另类视频在线观看+1080p| 极品国产人妖chinesets亚洲人妖 激情亚洲另类图片区小说区 | 亚洲国产欧美精品| 亚洲国产精品国自产拍久久| 手机版av在线| 欧美伦理在线视频| 欧美亚洲免费在线| 亚洲国产国产| 欧美午夜精品理论片a级大开眼界| 成人性生交大片免费看96| av在线亚洲男人的天堂| 蜜桃精品一区二区三区| 91精品视频在线播放| 国产欧美视频一区二区三区| 免费国产成人看片在线| 99tv成人| 成人在线观看www| 婷婷久久综合| 日本一区二区免费高清视频| 精品免费二区三区三区高中清不卡| 成人福利在线观看视频| 日韩中文av在线| 欧洲日本在线| 美乳少妇欧美精品| av网站导航在线观看免费| 久久99久久99精品中文字幕 | 久久蜜桃香蕉精品一区二区三区| 给我看免费高清在线观看| 久久日韩精品一区二区五区| 亚洲综合网在线观看| 中文字幕免费一区| 天天看片中文字幕| 亚洲国产精品一区二区www| 国产精品xxxx喷水欧美| 色诱视频网站一区| 中文字幕日产av| 欧美成人三级电影在线| 亚洲 欧美 激情 小说 另类| 亚洲无av在线中文字幕| 黄网站免费在线播放| 国内揄拍国内精品| 精品欧美日韩精品| 99久久99久久精品国产片| 日韩欧美美女在线观看| 午夜免费电影一区在线观看| 欧美.www| 不卡av免费在线| 亚洲熟妇av一区二区三区| 久久99精品视频| 日本五十肥熟交尾| 国产精品乱人伦中文| 久久久久亚洲天堂| 在线国产电影不卡| 午夜久久久久久噜噜噜噜| 亚洲欧美国产va在线影院| 国产在线高清理伦片a| 5278欧美一区二区三区| 国产精品日本一区二区不卡视频 | 天堂在线中文网| 久久精品视频免费播放| 手机av在线| 亚洲一区二区在线| 国产成人1区| 日韩精品一区在线视频| 加勒比av一区二区| 亚洲一级中文字幕| 亚洲国产视频网站| 国产老妇伦国产熟女老妇视频| 精品视频在线播放| 欧美色图天堂| 国产日韩欧美视频| 亚洲第一福利专区| 精品无码国产一区二区三区av| 麻豆久久久久久| 老鸭窝一区二区| 午夜亚洲国产au精品一区二区| 91福利在线观看视频| 亚洲三级黄色在线观看| 999福利在线视频| 91超碰rencao97精品| 日韩一区二区在线免费| 亚洲午夜精品久久久久久人妖| 国产精品羞羞答答xxdd| 肉色超薄丝袜脚交69xx图片| 色乱码一区二区三区88| 亚洲 另类 春色 国产| 久久久久国色av免费观看性色| 亚洲一区有码| 在线成人性视频| 强制捆绑调教一区二区| 亚洲日本精品视频| 欧美丝袜一区二区三区| 天天干天天操av| 97国产精品久久| 黄色欧美网站| 欧美午夜性视频| 豆国产96在线|亚洲| 99热精品免费| 日韩精品专区在线影院观看| a在线免费观看| 91老司机精品视频| 国产精品久久久久久久久妇女| 最近中文字幕一区二区| 欧美经典一区二区| 免费在线观看av的网站| 在线观看国产欧美| 国产精品蜜月aⅴ在线| 亚洲.欧美.日本.国产综合在线| 日韩影院精彩在线| 婷婷丁香综合网| 欧美日韩成人激情| 久草免费在线观看| 91视频99| 亚洲国产二区| 亚洲av无码一区二区三区网址| 亚洲成人免费av| 久久99久久| 国产精品视频精品| 亚洲视频电影在线| 成年女人免费视频| 欧美日韩国产区| 国产三级在线免费| 91精品免费视频| 亚洲香蕉网站| 成人h动漫精品一区| 在线观看日韩毛片| 久久黄色美女电影| 国产日韩久久| 久久国产高清| www中文在线| 精品国产乱码久久| 黑人巨大亚洲一区二区久| 亚洲免费视频一区| 国产高清精品在线| wwwwww国产| 中文字幕欧美专区| 51亚洲精品| 黄色av免费在线播放| 亚洲色图另类专区| 日韩在线一区二区三区四区| 久久午夜电影网| 久久久一二三区| 国产视频精品免费播放| 99精品在免费线偷拍| 精品无码av无码免费专区| 91在线丨porny丨国产| 中文字幕 亚洲视频| 欧美日韩福利视频| 欧美男男gaytwinkfreevideos| 亚洲18在线看污www麻豆| 亚洲一区视频在线| 风间由美一区| 国产精品久久7| 秋霞成人午夜伦在线观看| 久久久精品人妻一区二区三区四| 亚洲免费精彩视频| 98视频精品全部国产| 国产成人黄色网址| 午夜精品久久一牛影视| 欧美高清视频| 久久综合入口| 国产69精品一区二区亚洲孕妇 | jizzjizz亚洲| 日本黑人久久| 成人av网在线| 国产内射老熟女aaaa∵|