如何创建一个Sencha Touch 2应用_记事本案例(第五部分)
来源:互联网 发布:sql join on 多表 编辑:程序博客网 时间:2024/06/06 09:09
Many of the readers of this tutorial on how to build a Sencha Touch Application have requested a version of the Notes Application that shows how to create components using the config object, instead of the initialize function. In this chapter of the tutorial, we are going to do just that.
很多此系列教程的读者都在要求一个使用config创建视图控件的版本,而不是我们在前几节使用的在initailize()函数中添加控件。所以在这一章我们只是修改我们的应用,使用config来创建控件,仅此而已。
Using Sencha Touch’s Config Object to Create the Notes List(使用ST的config对象创建list)
The first step we are going to take is consolidate the Notes List Container View and Notes List View into a single View, which we will call Notes List View. This View has the same components that used to exist in the former Views:
第一步我们把NoteListContainer类和NotesList类合并为一个类:NotesList。这个视图包含的控件和前面的版本一样:
In the application’s view directory, we are going to delete the old NotesListContainer.js file, and leave only the NotesList.js and NoteEditor.js files:
修改之后的view目录是这样的:
Next, we are going to remove the existing code from the NotesList.js file, and define the NotesList class like so:
接下来我们这样定义NotesList类:
Ext.define("NotesApp.view.NotesList", { extend: "Ext.Container", requires:"Ext.dataview.List", alias: "widget.noteslistview", config: { layout: { type: 'fit' }, items: [{ xtype: "toolbar", title: "My Notes", docked: "top", items: [ { xtype: 'spacer' }, { xtype: "button", text: 'New', ui: 'action', itemId: "newButton" } ] }, { xtype: "list", store: "Notes", itemId:"notesList", loadingText: "Loading Notes...", emptyText: '<div class="notes-list-empty-text">No notes found.</div>', onItemDisclosure: true, grouped: true, itemTpl: '<div class="list-item-title">{title}</div><div class="list-item-narrative">{narrative}</div>' }], listeners: [{ delegate: "#newButton", event: "tap", fn: "onNewButtonTap" }, { delegate: "#notesList", event: "disclose", fn: "onNotesListDisclose" }] }, onNewButtonTap: function () { console.log("newNoteCommand"); this.fireEvent("newNoteCommand", this); }, onNotesListDisclose: function (list, record, target, index, evt, options) { console.log("editNoteCommand"); this.fireEvent('editNoteCommand', this, record); }});
If you are already familiar with the previous version of this View, you will notice that although the onNewButtonTap and onNotesListDisclose functions remain unchanged, we are now taking advantage of the config object to define the View’s items, and the event listeners needed for the New button and the disclose buttons of the notes List.
如果你已经对前面的版本很熟悉的话,你会看到虽然onNewButtonTap()和onNoteListDisclose()函数没做改变,但是我们却是用了config对象来配置视图的控件和事件。
Defining Event Listeners with Sencha Touch Config Objects(使用ST的config对象定义事件监听器)
The New button’s tap listener is pretty straightforward(坦率,直接,简单). Its delegate(代表) config is the value of the itemId config of the button. The fn config is a pointer to the onNewButtonTap function:
newButton的监听器很简单。他的delegate配置是按钮的id,然后fn配置指定事件处理函数。
{ delegate: "#newButton", event: "tap", fn: "onNewButtonTap"}We defined the List’s disclose handler in a similar fashion. The delegate points to the List’s itemId, and fn is the onNotesListDisclose function:
我们使用相同的风格来定义list的disclose监听器。
{ delegate: "#notesList", event: "disclose", fn: "onNotesListDisclose"}
Configuring the Note Editor(配置noteEditor)
Now we are going to move on to the NoteEditor View, where we will replace the initialize function with the config’s items and listeners properties:
我们到NoteEditor视图中我们将会用config对象来替换初始化函数中的代码:
Ext.define("NotesApp.view.NoteEditor", { extend: "Ext.form.Panel", requires: "Ext.form.FieldSet", alias: "widget.noteeditorview", config: { scrollable: 'vertical', items: [ { xtype: "toolbar", docked: "top", title: "Edit Note", items: [ { xtype: "button", ui: "back", text: "Home", itemId: "backButton" }, { xtype: "spacer" }, { xtype: "button", ui: "action", text: "Save", itemId: "saveButton" } ] }, { xtype: "toolbar", docked: "bottom", items: [ { xtype: "button", iconCls: "trash", iconMask: true, itemId: "deleteButton" } ] }, { xtype: "fieldset", items: [ { xtype: 'textfield', name: 'title', label: 'Title', required: true }, { xtype: 'textareafield', name: 'narrative', label: 'Narrative' } ] } ], listeners: [ { delegate: "#backButton", event: "tap", fn: "onBackButtonTap" }, { delegate: "#saveButton", event: "tap", fn: "onSaveButtonTap" }, { delegate: "#deleteButton", event: "tap", fn: "onDeleteButtonTap" } ] }, onSaveButtonTap: function () { console.log("saveNoteCommand"); this.fireEvent("saveNoteCommand", this); }, onDeleteButtonTap: function () { console.log("deleteNoteCommand"); this.fireEvent("deleteNoteCommand", this); }, onBackButtonTap: function () { console.log("backToHomeCommand"); this.fireEvent("backToHomeCommand", this); }});
We are following the same approach we used to configure the NotesList View. This time, we need listeners for the Back, Save and Delete buttons:
遵循在NoteList视图中的配置方法,为back,save,delete按钮配置监听器:
listeners: [ { delegate: "#backButton", event: "tap", fn: "onBackButtonTap" }, { delegate: "#saveButton", event: "tap", fn: "onSaveButtonTap" }, { delegate: "#deleteButton", event: "tap", fn: "onDeleteButtonTap" }]The onBackButtonTap, onSaveButtonTap, and onDeleteButtonTap function remain unchanged.
The onBackButtonTap, onSaveButtonTap, and onDeleteButtonTap函数都没有变化。
Adding View Instances to the Application(给应用添加视图引用)
In the app.js file, we are going to instantiate both Views as follows:
在app.js文件中,我们这样实例化两个视图:
Ext.application({ name: "NotesApp", models: ["Note"], stores: ["Notes"], controllers: ["Notes"], views: ["NotesList", "NoteEditor"], launch: function () { var notesListView = { xtype: "noteslistview" }; var noteEditorView = { xtype: "noteeditorview" }; Ext.Viewport.add([notesListView, noteEditorView]); }});
Modifying the Controller(修改控制器)
The Controller remains unchanged, with the exception of the Views aliases, which we have changed in the chapter of the tutorial:
由于视图类没有
Ext.define("NotesApp.controller.Notes", { extend: "Ext.app.Controller", config: { refs: { // We're going to lookup our views by alias. notesListView: "noteslistview", noteEditorView: "noteeditorview", notesList: "#notesList" }, control: { notesListView: { // The commands fired by the notes list container. newNoteCommand: "onNewNoteCommand", editNoteCommand: "onEditNoteCommand" }, noteEditorView: { // The commands fired by the note editor. saveNoteCommand: "onSaveNoteCommand", deleteNoteCommand: "onDeleteNoteCommand", backToHomeCommand: "onBackToHomeCommand" } } }, // Transitions slideLeftTransition: { type: 'slide', direction: 'left' }, slideRightTransition: { type: 'slide', direction: 'right' }, // Helper functions getRandomInt: function (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }, activateNoteEditor: function (record) { var noteEditorView = this.getNoteEditorView(); noteEditorView.setRecord(record); // load() is deprecated. Ext.Viewport.animateActiveItem(noteEditorView, this.slideLeftTransition); }, activateNotesList: function () { Ext.Viewport.animateActiveItem(this.getNotesListView(), this.slideRightTransition); }, // Commands. onNewNoteCommand: function () { console.log("onNewNoteCommand"); var now = new Date(); var noteId = (now.getTime()).toString() + (this.getRandomInt(0, 100)).toString(); var newNote = Ext.create("NotesApp.model.Note", { id: noteId, dateCreated: now, title: "", narrative: "" }); this.activateNoteEditor(newNote); }, onEditNoteCommand: function (list, record) { console.log("onEditNoteCommand"); this.activateNoteEditor(record); }, onSaveNoteCommand: function () { console.log("onSaveNoteCommand"); var noteEditorView = this.getNoteEditorView(); var currentNote = noteEditorView.getRecord(); var newValues = noteEditorView.getValues(); // Update the current note's fields with form values. currentNote.set("title", newValues.title); currentNote.set("narrative", newValues.narrative); var errors = currentNote.validate(); if (!errors.isValid()) { Ext.Msg.alert('Wait!', errors.getByField("title")[0].getMessage(), Ext.emptyFn); currentNote.reject(); return; } var notesStore = Ext.getStore("Notes"); if (null == notesStore.findRecord('id', currentNote.data.id)) { notesStore.add(currentNote); } notesStore.sync(); notesStore.sort([{ property: 'dateCreated', direction: 'DESC'}]); this.activateNotesList(); }, onDeleteNoteCommand: function () { console.log("onDeleteNoteCommand"); var noteEditorView = this.getNoteEditorView(); var currentNote = noteEditorView.getRecord(); var notesStore = Ext.getStore("Notes"); notesStore.remove(currentNote); notesStore.sync(); this.activateNotesList(); }, onBackToHomeCommand: function () { console.log("onBackToHomeCommand"); this.activateNotesList(); }, // Base Class functions. launch: function () { this.callParent(arguments); var notesStore = Ext.getStore("Notes"); notesStore.load(); console.log("launch"); }, init: function () { this.callParent(arguments); console.log("init"); }});
Summary
We just created a version of the Notes Application where, instead of the initialize function, we exclusively(仅仅) used config objects to configure each of the application’s Views. In the process(在此过程中), we learned how to create event listeners for components defined using config objects.
At this point, we have accomplished our goals for this application. I hope the insights(见解) you gained in this Sencha Touch tutorial will help you create great mobile applications.
这里我们只是创建了一个使用config对象配置视图的版本。我们仅仅使用config配置应用的视图,在这个过程中我们学习了怎么使用config对象为控件创建事件监听。
到此为止我们已经能实现了我们的目标,希望这个教程能给你一些灵感,让你创造出更加好的移动应用!
Downloads
Download the source code for this article: NotesApp-ST2-Part5.zip
The Entire Series
§ How to Create a Sencha Touch 2 App, Part 1
§ How to Create a Sencha Touch 2 App, Part 2
§ How to Create a Sencha Touch 2 App, Part 3
§ How to Create a Sencha Touch 2 App, Part 4
§ How to Create a Sencha Touch 2 App, Part 5
§
Want To Learn More?
My Sencha Touch books will teach you how to create an application from scratch.
§ Sencha Touch 2 Book
§ Sencha Touch 1 Book
What Sencha Touch Topics Would You Like Me To Write About?
I’d like to help you learn Sencha Touch better and faster, but I need you to let me know what subjects you are curious about, or what topics you are struggling with.
Please send me your questions or suggestions for future posts at miamicoder[AT]gmail.com.
TAGGED WITH: SENCHA TOUCH TUTORIAL 58 COMMENTS
About Jorge
Jorge is the author of Building a Sencha Touch Application, How to Build a jQuery Mobile Application, and the Ext JS 3.0 Cookbook. He runs a software development and developer education shop that focuses on mobile, web and desktop technologies.
If you'd like to work with Jorge, contact him at ramonj[AT]miamicoder.com.
- 如何创建一个Sencha Touch 2应用_记事本案例(第五部分)
- 如何创建一个Sencha Touch 2应用_记事本案例
- 如何创建一个Sencha Touch 2应用_记事本案例(第三部分)
- 如何创建一个Sencha Touch 2应用_记事本案例(第一部分)
- 如何创建一个Sencha Touch 2应用_记事本案例(第四部分)
- 如何创建一个Sencha Touch 2应用_笔记本案例(第二部分)
- 如何创建一个Sencha Touch 2应用(第一部分)
- 如何创建一个Sencha Touch 2应用(第一部分)
- 如何创建一个SENCHA TOUCH 2应用
- 如何创建一个Sencha Touch 2应用(序言)
- Sencha Touch开发实例:记事本应用(一)
- Sencha Touch开发实例:记事本应用(二)
- Sencha Touch开发实例:记事本应用
- 创建Sencha touch第一个应用
- Sencha Touch 2 的运行环境 案例
- sencha-touch-1.1如何隐藏一个工具条
- Sencha Touch中如何alert显示一个sencha对象?
- 【翻译】Sencha Touch 2入门:创建一个实用的天气应用程序之一
- 黑马程序员之ADO.NET学习笔记:.NET中被大家容易忽视的问题
- 触发器与存储过程的相互调用
- android 自定义进度条颜色
- Weblogic 修改端口号步骤
- C#中的MessageBox消息对话框
- 如何创建一个Sencha Touch 2应用_记事本案例(第五部分)
- strlen与sizeof区别(转载)以及struct,union的sizeof内存对齐等问题
- Android资源引起的程序崩溃
- 设置HOST-ONLY工作模式实现VIRTUALBOX寄主机与虚拟机互访
- PT与PX区别
- 上机题专家打分
- ServicePoint的详解
- DMAIC && DFSS of 6sigma
- iOS开发笔记--URL重定向 URL redirect