如何在一个视图中合并两个控制器。
我有两个控制器:
1。 PostController
2。 CommentController
帖子控制器将显示数据库中的所有帖子,帖子可以有评论。对于评论,我使用另一个控制器CommentController
来避免干。在html帖子列表中循环时我试图附加评论,如果所有帖子都存在于他们的ID上。
在我的PostController
> indexAction()
我正在抓取所有帖子
// controllers/PostController.php
/**
* List all posts
*
*/
public function index()
{
$data = array(
'posts' => $this->post->findAll(),
);
$this->load->view('post/index', $data);
}
以下是comment controller
列出post_id
的评论的方法:
// controllers/CommentController.php
/**
* List all comments assigning post id
*
* @param int $post_id
*/
public function index($post_id)
{
$data = array(
'comments' => $this->comment->findAllByPostId($post_id), // <-- SELECT * FROM comments WHERE post_id = {post_id}
);
$this->load->view('comment/index', $data);
}
现在在post/index
我正在抓取所有帖子:
<?php if($posts): ?>
<?php foreach ($posts as $post): ?>
<h1> <?= $post->title; ?> </h1>
<div> <?= $post->text; ?> </div>
<div class="comment-list">
<!-- How to call here comment controller and index($post->post_id) -->
<!-- i can use load->view('comment/index') but with this i do nothin i need to assigning post id
<!-- Need somthing $commentObject->index($post->post_id) but this in MVC is not good idea -->
</div>
<?php endforeach() ;?>
<?php endif; ?>
还有其他解决方案吗?
我解决这个问题的方法是将所有内容放在一个控制器Post
中。但我认为这是不好的做法bcs我将干后。我需要其他ex的评论控制器(PictureController也可以有评论,我不想要DRY)
也许我的流程或组织不好?
PS。我为此搜索SO,但结果对我没有帮助
答案 0 :(得分:1)
控制器从模型中获取数据。所以一般情况下,任何数据库交互都会在模型中发生,然后该控制器会询问“你收到了我的信息吗?如果是,则显示它,如果没有,则执行其他操作”当所有内容都被整理出来时,数据会被发送到视图。
一个控制器可以从许多不同的模型调用,并且可以向视图发送多个数据结构。
public function index()
{
// assuming you have a model called 'post'
// check if any posts came back from the search
if( ! $posts = $this->post->findAll() )
{
$this->_showNoPostsReturned() ;
}
// now assuming you have a model called comment
// in your model you will have to foreach through posts etc
// did any comments come back?
elseif( ! $comments = $this->comment->returnFor($posts) )
{
$this->_showOnlyThe($posts) ;
}
// else we have posts and comments
else{ $this->_showBoth($posts,$comments) ; }
}
private function _showBoth($posts,$comments){
// this is how you pass more then one data structure
// array, object, text, etc etc
// with $data['name']
$data['posts'] = $posts ;
$data['comments'] = $comments ;
// and call more then one view if necessary
$this->load->view('post/index', $data);
$this->load->view('comment/index', $data);
}
所以这个索引方法只是要求模型中的数据,然后根据它获取的数据是什么 - 它调用一个单独的私有方法,该方法可以调用适当的视图。换句话说,现在您不需要在视图中执行此操作
<?php if($posts): ?>
这就是你想要避免的,因为那时视图正在决定要展示什么。显然,某些逻辑将在视图中发生,但所有决策都应尽可能在控制器中发生。
答案 1 :(得分:0)
<强>元强>
首先,我认为你确实想干,因为干意味着'不要重复自己'#34;。我认为你已经掌握了这个概念,但是读到你并不想干涸&#34;有点令人困惑;)
<强>答案强>
其次:在经典的MVC方法中(CodeIgniter确实如此),确实让控制器处理当时(或来自它的数据)传递给视图的模型。
现在有关于如何从控制器中检索所需数据的不同概念,例如:真正在控制器中读取所有内容然后将其传递给视图,而不是只传递&#34; post&#34;模型并让视图在视图中取出帖子评论。我认为两者都有正当理由,你可以决定使用哪一个(也有其他人!),即使我更喜欢后者。
一种替代方法可能是使用"Decorator Pattern" (see Wikipedia),它似乎只在CodeIgniter中具有用户态实现:https://github.com/ccschmitz/codeigniter-decorator
<强> TL; DR 强>
你的方法很好,但你可能会研究装饰模式(见上文)。