Codeigniter在视图中调用其他控制器

时间:2016-01-12 16:02:31

标签: php codeigniter model-view-controller

如何在一个视图中合并两个控制器。

我有两个控制器:

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,但结果对我没有帮助

2 个答案:

答案 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

你的方法很好,但你可能会研究装饰模式(见上文)。