我有一个应用程序,其中有几个控制器专用于它们自己的部分,比如“新闻”,“文章”和“商店”。它们彼此没有连接,但它们应该是,因为我需要从它们插入数据,例如与当前商店类别相关的新闻。我还没有找到一种干净的方法来访问除当前处理请求之外的控制器。
模块的结构是:
Site.pm
是主项目文件。Articles.pm
处理文章。News.pm
处理新闻。Shop.pm
处理商店。 Site.pm
从模块名称数组中动态加载上述每一项,并调用其register
函数来设置启动时的路由和其他内容。文章,新闻等都从数据库中获取内容,并且它被呈现为内联模板,因此,我不能仅仅获取相关新闻并将其抨击藏匿,因为并非商店中的所有条目都可能需要该信息。
答案 0 :(得分:4)
这是没有代码的理论答案。
您可能将数据库内容与实际控制器分离为模型。这很好。
因此,让我们假设我们在商店里,我们想要展示与当前产品相关的新闻。至少有两种方法可以做到这一点。
您可以直接致电您的模特。您的新闻模型提供了获取产品新闻的方法。您可以在显示产品页面的车间控制器中执行此操作。该控制器需要将这些东西放在存储中,以便模板可以访问它。
您在新闻控制器中创建了一个无法从外部访问的方法。您需要获取产品ID并查找相关新闻文章并将其填充到存储中。您可以从商店控制器中的产品页面控制器转发它。然后,产品页面控制器继续。这是更加分离的方式。
在这两种情况下,您的商店模板都包含另一个模板,该模板知道如何处理存储中用于显示新闻的内容。您可以在此处回收新闻模板。
答案 1 :(得分:0)
我没有参与Mojolicious,但IMO这是最好的方法 -
您的站点控制器应该将GET请求发送到它想要的任何其他控制器,这些控制器应该返回JSON数据,然后可以在客户端呈现。看看Rendering JSON。希望有所帮助。
答案 2 :(得分:0)
根据我的经验,编码 - 血液,以及我的代码的很多耻辱,我建议: 控制器中的每个方法只应调用单个函数并将结果传递给模板。这在某种程度上类似于@simbabque的答案。
这将帮助您稍后测试控制器,编写API而不是提供html模板,甚至完全更改框架(只要它是Perl)。
所以,我会在Controller和Models之间添加一个可选层:
$t->get('/books/:id')->to('books#get')
sub Books::get{ my $self = shift; my $book = FBooks::get($self->param('id')); # plus template call }
sub FBooks::get{ # here you call your Model }
# your Model calls your DB
你提供FBooks :: get只有当你需要多次调用你的模型时(也许这不是一个完美的例子,但我希望你明白我的观点)。我更喜欢这个而不是帮助大军。如果还有其他更好的方法,我很乐意学习它。