Статьи

Написание приложения Sencha Touch, часть 2

В первой части этого руководства Sencha Touch мы начали создавать приложение, позволяющее пользователю делать заметки и сохранять их на устройстве. Создав основу приложения, мы находимся в процессе создания представления списка заметок, которое на данный момент выглядит следующим образом:

В этом представлении отсутствует Ext.list, который будет отображать заметки, созданные пользователем, и кнопку «Создать» на панели инструментов, как показано в макете, который мы создали в первой части этого урока:

 

Давайте работать над списком заметок.

Создание модели данных в Sencha Touch

Прежде чем мы сможем создать список, нам нужно создать модель данных, которая будет представлять заметку. Мы делаем это с помощью метода Ext.regModel ():

Ext.regModel('Note', {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'date', type: 'date', dateFormat: 'c' },
{ name: 'title', type: 'string' },
{ name: 'narrative', type: 'string' }
],
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'title' }
]
});

Наша модель Note, как и любая модель данных в Sencha Touch , определяется как набор полей и относящихся к ней методов и свойств. Модель имеет встроенную поддержку валидации, которую мы используем, чтобы с помощью опции config validations утверждать, что для свойств id и title требуется значение. Мы увидим, как происходит проверка модели при создании редактора заметок.

Модели данных также поддерживают связи с другими моделями посредством отношений «есть много» и «принадлежность». Хотя мы не будем использовать ассоциации в этом руководстве, я призываю вас ознакомиться с их документацией и примерами. Скорее всего, вы столкнетесь с ассоциациями при создании приложений Sencha Touch.

Настройка хранилища данных Sencha Touch для использования локального хранилища HTML5

Нам также нужен механизм для кэширования наших заметок. Функция Ext.regStore () позволяет нам создать хранилище данных, наш кэш заметок, например:

Ext.regStore('NotesStore', {
model: 'Note',
sorters: [{
property: 'date',
direction: 'DESC'
}],
proxy: {
type: 'localstorage',
id: 'notes-app-localstore'
}
Ext.regStore('NotesStore', {
model: 'Note',
sorters: [{
property: 'date',
direction: 'DESC'
}],
proxy: {
type: 'localstorage',
id: 'notes-app-localstore'
}
});
});

Ext.regStore () создает и регистрирует хранилище с помощью диспетчера хранилища инфраструктуры . Как и другие классы в платформе, вы можете использовать Менеджер магазина для поиска и изменения хранилищ данных в вашем приложении.

Опция конфигурации модели нашего NotesStore — это модель Note. Мы также используем опцию сортировщиков, чтобы указать, что заметки будут отсортированы по дате в порядке убывания.

Помните, что одной из функций нашего приложения является возможность сохранять заметки между сеансами браузера? Задача загрузки и сохранения данных модели делегируется на прокси магазина. Мы используем опцию конфигурации прокси, чтобы определить наш прокси как экземпляр класса Ext.data.LocalStorageProxy . Этот класс использует HTML5 localStorage API для локального сохранения данных модели в клиентском браузере. Я считаю эту абстракцию API локального хранилища одной из самых приятных особенностей инфраструктуры Sencha Touch.

Создание сенсорного списка Sencha

Когда модель данных и хранилище готовы, мы можем создать список заметок следующим образом:

NotesApp.views.notesList = new Ext.List({
id: 'notesList',
store: 'NotesStore',
itemTpl: '
<div class="list-item-title">{title}</div>
' +
'
<div class="list-item-narrative">{narrative}</div>
'
});

Здесь ничего сложного. Список будет использовать NotesStore, передаваемый по имени через опцию конфигурации хранилища. Мы определяем разметку, используемую для визуализации заметок, с помощью опции конфигурации itemTpl. В разметке используются классы list-item-title и list-item-narrative, которые мы добавим в файл app.css:

.list-item-title
{
float:left;
width:100%;
font-size:90%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.list-item-narrative
{
float:left;
width:100%;
color:#666666;
font-size:80%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.x-item-selected .list-item-title
{
color:#ffffff;
}
.x-item-selected .list-item-narrative
{
color:#ffffff;
}

Теперь давайте добавим список на панель контейнера, используя опцию конфигурации элементов панели:

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

Хотите сделать быстрый бег на симуляторе, чтобы увидеть, как у нас дела? Хорошо, но прежде чем мы это сделаем, давайте добавим фиктивную заметку в NotesStore, чтобы мы могли видеть, как список отображает заметку. Мы можем сделать это, используя опцию конфигурации данных:

Ext.regStore('NotesStore', {
model: 'Note',
sorters: [{
property: 'date',
direction: 'DESC'
}],
proxy: {
type: 'localstorage',
id: 'notes-app-store'
},
// TODO: remove this data after testing.
data: [
{ id: 1, date: new Date(), title: 'Test Note', narrative: 'This is simply a test note' }
]
});

На эмуляторе устройства представление списка заметок должно выглядеть следующим образом:

На данный момент наш список заметок почти готов. Мы добавили панель инструментов, список заметок, модель данных и хранилище, которое будет кэшировать заметки. Нам просто не хватает двух навигационных средств, которые позволят пользователю открывать представление редактора заметок: кнопка «Создать» на панели инструментов и кнопка раскрытия информации в каждом элементе списка.

Добавление кнопок на панель инструментов Sencha Touch

Вот как мы добавляем кнопку «Новый» на панель инструментов:

NotesApp.views.notesListToolbar = new Ext.Toolbar({
id: 'notesListToolbar',
title: 'My Notes',
layout: 'hbox',
items: [
{ xtype: 'spacer' },
{
id: 'newNoteButton',
text: 'New',
ui: 'action',
handler: function () {
// TODO: Create a blank note and make the note editor visible.
}
}
]
});

Использование компоновки hbox и добавление проставки на панель инструментов позволяет нам нажимать кнопку New до упора вправо. Мы ненадолго оставим функцию обработчика в покое. После создания представления редактора заметок мы добавим код, чтобы открыть редактор из этого обработчика.

Реализация кнопок раскрытия в списке Sencha Touch

Кнопку раскрытия также очень легко реализовать с помощью опции конфигурации onItemDisclosure:

NotesApp.views.notesList = new Ext.List({
id: 'notesList',
store: 'NotesStore',
itemTpl: '
<div class="list-item-title">{title}</div>
' +
'
<div class="list-item-narrative">{narrative}</div>
',
onItemDisclosure: function (record) {
// TODO: Render the selected note in the note editor.
}
});

Мы используем одно из переопределений onItemDisclosure, чтобы привязать слушателя к событию касания в любом элементе списка. Все, что нам нужно будет сделать внутри этого слушателя, это взять запись, которая получила сигнал, и передать ее в представление редактора заметок. Но мы закончим этот обработчик позже, после создания нашего редактора заметок.

Где мы?

Давайте остановимся на еще одной быстрой проверке на симуляторе. Приложение должно выглядеть так:

Здорово! Мы завершили основной вид приложения, за исключением двух обработчиков событий, которые позволят нашим пользователям перейти к редактору заметок.

Теперь мы готовы начать работу с редактором заметок:

Но это произойдет в следующей главе этой серии. Сейчас я оставлю вам исходный код приложения на этом этапе:

var App = new Ext.Application({
name: 'NotesApp',
useLoadMask: true,
launch: function () {

Ext.regModel('Note', {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
{ name: 'date', type: 'date', dateFormat: 'c' },
{ name: 'title', type: 'string' },
{ name: 'narrative', type: 'string' }
],
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'title' }
]
});

Ext.regStore('NotesStore', {
model: 'Note',
sorters: [{
property: 'date',
direction: 'DESC'
}],
proxy: {
type: 'localstorage',
id: 'notes-app-localstore'
},
// TODO: remove this data after testing.
data: [
{ id: 1, date: new Date(), title: 'Test Note', narrative: 'This is simply a test note' }
]
});

NotesApp.views.notesList = new Ext.List({
id: 'notesList',
store: 'NotesStore',
itemTpl: '
<div class="list-item-title">{title}</div>
' +
'
<div class="list-item-narrative">{narrative}</div>
',
onItemDisclosure: function (record) {
// TODO: Render the selected note in the note editor.
}
});

NotesApp.views.notesListToolbar = new Ext.Toolbar({
id: 'notesListToolbar',
title: 'My Notes',
layout: 'hbox',
items: [
{ xtype: 'spacer' },
{
id: 'newNoteButton',
text: 'New',
ui: 'action',
handler: function () {
// TODO: Create a blank note and make the note editor visible.
}
}
]
});

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

NotesApp.views.viewport = new Ext.Panel({
fullscreen: true,
layout: 'card',
cardAnimation: 'slide',
items: [NotesApp.views.notesListContainer]
});
}
});

Оставайтесь в курсе! И не забудьте оставить свои комментарии или предложения.:-)

 

От http://miamicoder.com/2011/writing-a-sencha-touch-application-part-2