Sencha Touch MVC - рекомендуемые способы передачи данных через контроллер?
Я использую Sencha Touch для мобильного приложения и использую в нем функции MVC. Мне очень нравится Sencha, но у меня небольшие проблемы, когда речь идет о передаче данных с одного экрана на другой с помощью контроллера.
Здесь есть свойство "record", связанное с рядом виджетов Sencha - например, указав текущую выбранную запись в Ext.list, и по какой-то причине я не могу понять, как передать что-то как от Ext.Panel до другого.
Например, у меня есть Ext.Panel с данными в нем из Ext.Store, включая адрес. У меня есть еще одна Ext.Panel, которая покажет карту. Мне нужно передать этот адрес на панель карты, но я не уверен, как это сделать. Вот что я пытаюсь с первой панели:
listeners: {
'tap': function () {
Ext.dispatch({
controller: app.controllers.establishments,
action: 'showMap',
id: record.getId(),
data: record.data
});
}
Я немного пошатываюсь, как вы можете видеть, пытаясь использовать опцию конфигурации "id" и "data" в контроллере, пытаясь получить данные на панели карты любыми средствами.
Мне не обязательно нужен ответ на эту конкретную проблему, но если у вас есть предложения о том, как это сделать в целом - в основном, лучшие практики для передачи данных с одного экрана на другой.
Если это помогает, я основываю свою структуру приложения на хорошем учебнике MVC мистера Пирса в Sencha:
http://www.sencha.com/learn/Tutorial:A_Sencha_Touch_MVC_application_with_PhoneGap
Спасибо большое!
Ответы
Ответ 1
Я думаю, что вы на правильном пути с Ext.Dispatch. Параметры, добавляемые в объект опций отправки, передаются методу действия на контроллере.
например.
showMap: function(options){
var id = options.id;
//load data based on the id and pass it to your map
...
}
Я также думаю, что вы должны установить historyUrl на объект опций отправки, чтобы, если они обновили страницу, идентификатор все равно будет отправлен на действие контроллера.
Ответ 2
Я не очень хорошо знаком с этим шаблоном MVC, но у меня большой опыт работы с ExtJS, и, на мой взгляд, лучший способ общения с компонентами - это события. В вашем примере вы создадите событие на панели, например "addAddress", и Map будет прослушивать это событие. И когда адрес был установлен в панели, вы должны позвонить.
this.addEvent('addAddress');
this.fireEvent('addAddress', this, address);
и на карте будет такой слушатель, как
onAddress: function(panel, address) {
// do something with the address
}
и в вашем приложении верхнего уровня вы добавите слушателя.
app.mon(panel, 'addAddress', map.onAddress, this);
Как правило, это лучше всего подходит для ваших компонентов таким образом, чтобы панель не зависела от Карты и наоборот
Ответ 3
Лучшим решением может быть реструктуризация вашего MVC, чтобы исключить необходимость пропускать записи вокруг разных представлений. Например, при создании другого компонента представления используется один и тот же магазин, ссылка на который сделана доступной из любой точки.
Обычно я помещал ссылку на магазины, используемые в разных представлениях, в таких местах, как App.controllers.data
и непосредственно под App
(что в действительности является частью контроллера).
Ответ 4
Отвечая на очень старый вопрос, я полагаю, что с текущими версиями Sencha touch (2.2+) у нас есть альтернативный метод, который я предпочитаю. Здесь это для вашей оценки.
Альтернативой является использование функции маршрутов контроллеров.
ПРИМЕЧАНИЕ. Ext.Dispatch устарела в Sencha Touch 2.2, если вы все еще хотите использовать метод отправки, вам нужно получить контроллер и вызвать метод на нем, как описано здесь. Как передавать данные среди экранов в sencha touch2.0?
Сначала вы определяете маршруты, которые интересует контроллер.
Ext.define('My.controller.Profile', {
extend: 'Ext.app.Controller'
,config: {
routes: {
'products/:id': 'showProduct'
}
}
,showProduct: function(id) {
console.log('Load and Show product... ' + id);
}
});
Затем вы создаете ссылку с URL-адресом этого формата как href:
<a href="#products/1234">View Product</a>
При щелчке по ссылке вызывается метод Product controllers showProduct
с id
, установленным на 1234.
Или, если вы хотите сделать это программно, вы можете написать:
location.hash = "products/1234";
который будет иметь тот же эффект.
Я думаю, что это чистая, слабосвязанная и менее зависимая от внутренних фреймов. Открыт для идей.:)