Где разместить в MVC таблицу диспетчеризации?
Таблица диспетчеризации (или метод диспетчеризации) является одновременно таблицей (моделью) и маршрутизатором / контроллером.
Представьте себе навигацию с вкладками, где может быть 30 вкладок для различных конечных пользователей. Каждая вкладка - это, по сути, страница, у которой есть собственный контроллер и представления. В моем случае таблица отправки содержит ключи для вкладок, а затем данные для каждой вкладки (путь, displayName, видимость и т. Д.).
my $tabs = {
Home => {
action => \&HomeController::dashboard,
displayName => ‘Home’,
...
},
About => {
action => \&AboutController::info,
displayName => ‘About Us’,
...
},
...
};
Изначально у меня были TabController и TabView. Внутри контроллера была таблица диспетчеризации; однако он, похоже, не соответствовал MVC. Это выглядело нормально, когда было всего 3 вкладки, но по-другому, когда оно увеличивалось, особенно потому, что требовалось обрезать или фильтровать представления.
Имеет смысл переместить его в модель, поскольку он больше рассматривался как таблица данных. Однако, поскольку это Perl (и таблица диспетчеризации), все соответствующие пакеты также должны быть загружены. Таким образом, эта TabModel загружает множество контроллеров (и в некоторых случаях представления). Мне не очень нравится загружать / ссылаться на какие-либо контроллеры в модели, поэтому загрузка multi кажется еще хуже.
Есть ли лучшая практика или пример для этого сценария?
Дополнение
В попытке представить что-то более осязаемое. Я попытаюсь создать для этого временное веб-приложение. Это только концептуальный пример, он не полностью рабочий и многого не хватает; но, надеюсь, следует добавить немного больше описания и контекста. Он имеет следующую структуру каталогов:
index.pl -- entrance
Controllers/
-- Dashboard.pm
-- Home.pm
-- About.pm
Models/
-- Tabs.pm
-- Users.pm
Views/
-- Dashboard.pm
-- Home.pm
-- About.pm
-- Error.pm
Я не буду разбирать index.pl, но он, по сути, анализирует параметры и направляет на DashboardController:: dashboard.
DashboardController
package Controllers::Dashboard;
sub dashboard{
my $users = Models::Users::get_all(); # Users Model
my $tabs = Models::Tabs::get_permitted( # Tabs Model
$users->{CURRENT_USER}{permissions}
);
print Views::Page::render($users,$tabs); # Page View
}
О Контроллере
package Controllers::About;
sub info {
# No models necessary
print Views::About::render();
}
ВкладкиМодель
package Models::Tabs;
use Controllers::Home;
use Controllers::About;
sub get_all {
my $tabs = {
Home => {
action => \&Controllers::Dashboard::dashboard,
displayName => ‘Home’,
...
},
About => {
action => \&Controllers::About::info,
displayName => ‘About Us’,
...
},
...
};
return $tabs;
}
sub get_permitted {
my $user_permissions = shift;
my $tabs = get_all();
if (defined $user_permissions){
foreach my $tab (keys %$tabs){
delete $tabs->{$tab} unless $user_permissions->{"can_access_$tab"};
}
}
}
DashboardView
package Views::Dashboard;
sub render {
my ($users,$tabs) = @_;
my $html_tabs = '<ul>';
foreach my $tab (values %$tabs){
$html_tabs .= "$tab->{displayName}";
}
$html_tabs .= '</ul>;
my $html = <<"END";
$html_tabs
<!-- dashboard content -->
END
return $html;
}
1 ответ
древний вопрос, но сегодня он всплыл в ленте
Я думаю, что есть что-то шаткое в том, как вы распределяете вещи по категориям. Модели обычно являются источниками данных, и им все равно, что вы с ними делаете или как вы их отображаете. Однако вы вставили часть представления (презентации) в модель. Мне кажется, что Tabs.pm должен быть частью некоторого представления.
И то, что диспетчерская таблица является таблицей, не означает, что она является источником данных. Это особый метод решения проблемы, не связанной с конкретными данными или конкретным представлением. Если бы вы выполнили ту же задачу без таблицы диспетчеризации, вы бы не перенесли эту ответственность внезапно в другую часть MVC.