Где разместить в 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.

Другие вопросы по тегам