ExtJS 4 MVC несколько экземпляров представлений и проблем с дочерними контроллерами
Я столкнулся с проблемой с шаблоном MVC в ExtJS 4. По крайней мере, я думаю, что у меня есть. Подходя к нескольким людям с этим вопросом и неоднократно выставляя на форумах Sencha, я теперь обращаюсь к более широкой аудитории в надежде получить либо лампочку, либо подтверждение.
Проблема
Ваше приложение имеет возможность открывать много разных видов, некоторые из которых сами являются мини-приложениями. Кроме того, пользователь может захотеть открыть несколько параллельных копий открытого вида.
Это приложение представляет собой одностраничное клиентское приложение Javascript.
Модель ExtJS 4 MVC предполагает, что вы определяете все свои контроллеры в своем классе Application. Эти контроллеры затем инициализируются, когда приложение загружается. Контроллеры отслеживают просмотры, модели и магазины.
Когда вы несколько раз инициализируете контроллер A, скажем, чтобы создать несколько копий представления, вы получаете два представления, которые ссылаются на одни и те же хранилища данных, и функционально отправляют повторяющиеся события на шину событий приложения.
Я обновил свое приложение, добавив новые методы прототипов к компоненту и контроллеру, чтобы разрешить как: а) субконтроллеры (некоторые из моих контроллеров стали довольно большими), и b) определение магазинов специально для представления, с которым они работают. Модели все еще могут быть определены на контроллере, просто для удобства использования обработчиками, если вам нужно сделать что-то вроде захвата записи с сервера.
Вопрос
Мое понимание MVC привело бы меня к мысли, что модели более непосредственно связаны с представлением, чем с контроллером. Я утверждаю, что ExtJS 4 решает приложить хранилища (которые, как я думаю, можно рассматривать как обертки к более классической модели), для контроллеров в целях поощрения повторного использования загруженных данных и для оптимизации от множества копий тот же класс создается. Мне кажется, однако, что это невозможно сделать, если вы намерены иметь много экземпляров представления, доступных пользователю. По моему мнению, наличие большого количества экземпляров является важным вариантом в OO-структуре, поэтому я отменил эту тенденцию и реализовал прототипы некоторых базовых классов Ext. (Спасибо Ext.implement!).
Есть ли способ иметь несколько параллельных экземпляров представления с различными данными, загруженными в них, используя классы из класса MVC и использование используемых сеттеров, геттеров и т.д.?
Ответы
Ответ 1
У меня возникла аналогичная проблема:
Рассмотрим вкладку для приложения типа CRM, которое открывает новые экземпляры представления для каждого клиента. И скажите, что представление табуляции содержит 3 или 4 сетки для редактирования строк для взаимодействия с различными коллекциями данных, относящихся к этому клиенту.
Решение, с которым я столкнулся, основано на этом на форумах Sencha. В оболочке ореха почти все события, отправленные из представления, содержат ссылку на представление. Обработчики в моей функции управления контроллером все используют их, чтобы получить ссылку на правильный экземпляр представления.
Для работы с несколькими экземплярами одного и того же хранилища, необходимых для этого, я принял это близко к сердцу из этого сообщения:
Для экземпляра Store в представлении или глобальном... зависит от необходимо. Если вы собираетесь использовать глобально, сделайте его глобальным. если ты только понадобится это на вид, а затем поместить его в представление. MVC является а не закон, вы можете изменить его в соответствии с вашими потребностями. Технически Контрольная часть MVC должна быть средним человеком между View и Model, но иногда это просто не нужно. я создаю Store в представлении 95% времени. Я приведу вам пример...
Если у вас есть Магазин для продуктов, вам, вероятно, нужно только ссылаться что Store в вашей сетке. Это обычно не требуется для других частей приложение. Однако, если у вас есть магазин для загрузки стран, я часто нуждаются в нем в глобальном масштабе, поэтому мне нужно только загрузить его один раз, и тогда set/use, который хранится в нескольких представлениях.
Итак, я просто создал необходимый магазин, который специально относится к экземпляру вида, внутри метода initComponent. В приложении было несколько глобальных магазинов, которые я создал в качестве классов магазинов в соответствии с рекомендациями MVC. Он отлично работал, чтобы инкапсулировать хранилища экземпляров представления в представлении. Тогда мне нужен только один экземпляр контроллера.
Чтобы конкретно ответить на ваш вопрос, в настоящее время нет официальной рекомендации или конфигурации ExtJS для работы с несколькими экземплярами одного и того же представления, которые используют один и тот же конструктор хранилища. Я потратил некоторое время на то, чтобы найти что-то подобное, и лучшее, что я нашел, это рекомендация от одного из их модераторов форума.
Ответ 2
Я не думаю, что вам понадобится больше одного экземпляра контроллера, независимо от того, сколько просмотров/моделей у вас есть. См. Здесь функциональный пример:
http://whatisextjs.com/extjs-4-extension/fieldset-w-dynamic-controls-7
Ответ 3
Это можно сделать, достаточно легко. Вы должны следовать нескольким правилам:
-
загрузите свои контроллеры при запуске приложения. Не выгружайте их. Не беспокойтесь о памяти или времени, это довольно мало даже для сотен контроллеров, если вы минимизируете и объединяете свои js.
-
Никогда не используйте свойства refs или views контроллера. Вы собираетесь использовать один экземпляр контроллера, но несколько экземпляров представлений, поэтому вам никогда не нужна ссылка на представление.
-
используют только прослушиватели событий в контроллерах. Вы только будете слушать события на своих взглядах. Вы всегда можете получить (временную) ссылку на представление в обработчике событий с помощью параметра "cmp" в обработчике.
-
Чтобы "запустить" представление, создайте его и добавьте в другое представление. Уничтожить его, уничтожить. Вы не используете контроллер для запуска представления. Вы можете использовать afterrender и beforedestroy события в контроллере для добавления логики.
Ответ 4
В ExtJS 'MVC контроллер представляет собой Singleton для просмотра. Мне нравится, как DeftJS думает о MVC. Каждый экземпляр представления имеет собственный экземпляр контроллера. Таким образом, вы можете поместить все "управляющие правила" в контроллер для определенной части вашего представления, и это будет создаваться только тогда, когда открывается представление.
У меня не было никакого опыта, как я мог использовать несколько JS-приложений Defts в том же проекте.
Ответ 5
Конечно. Что заставило вас поверить иначе?
Ниже приведен пример создания пользовательского вида, который простирается от компонента Window. Вы можете запустить этот метод много раз с одного и того же контроллера и каждый раз, когда вы получите новый экземпляр представления.
"this" относится к контроллеру, в котором код работает:
this.getRequestModel().load(requestID,{ //load from server (async)
success: function(record, operation) {
var view = Ext.widget('requestEdit',{
title: 'MyRequest '+requestID
});
var form = view.down('form');
form.loadRecord(record);
}
});
Ответ 6
Как вы создаете свои представления? Я не вижу причин, по которым вы не можете передавать разные хранилища или данные конфигурации каждому объекту. Некоторые примеры кода помогут вам в том, что именно вы делаете. Например, у нас есть аналогичное приложение для звучания, и все делается с расширениями. Итак, если нам нужна сетка, мы запускаем
Ext.define('MyApp.grids.something',{
extends:'Ext.grid.panel'
//...
Эти классы предопределены. Затем, когда контроллер или представление загружает эту сетку, они используют
var grid=Ext.create('MyApp.grids.something',{id:'unique',store:mystore});
Как вы можете видеть, мы можем передавать разные параметры конфигурации в одну и ту же сетку каждый раз, когда она создается. Мы можем рассматривать это точно так же, как вы относитесь к
Ext.create('Ext.grid.Panel');
За исключением, конечно, что мы предопределяем некоторые предопределенные параметры и некоторые не переопределяемые и т.д.
Надеюсь, что это помогло.
Ответ 7
Отметьте этот пост. Идея состоит в том, чтобы выполнить некоторую конфигурацию (например, store
и itemId
) из конфигурации вида и поместить ее в конфигурацию видового экрана:
// .../app/view/Viewport.js
Ext.define('MyApp.view.Viewport', {
// ...
items: [
// ...
{ xtype: 'testview', store: 'Store1', itemId: 'instance1' },
{ xtype: 'testview', store: 'Store2', itemId: 'instance2' }
]
});
Проблема с магазином будет решена, очевидно. Различные itemId
позволят вам правильно обрабатывать события.