【问题标题】:Codeigniter call other controller in viewCodeigniter 在视图中调用其他控制器
【发布时间】:2016-01-12 16:02:30
【问题描述】:

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

我有两个控制器:

1.后控制器

2. 评论控制器

帖子控制器将显示数据库中的所有帖子,并且帖子可以有 cmets。对于 cmets,我使用另一个控制器 CommentController 来避免 DRY。在循环的 html 帖子列表中,如果所有基于其 ID 的帖子都存在,则尝试附加 cmets。

在我的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 的 cmets:

// 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 中。但我认为这是不好的做法,因为我稍后会干。我需要其他 ex 的评论控制器(PictureController 也可以有我不想要 DRY 的 cmets)

也许我的流程或组织不好?

ps。我搜索这个,但结果对我没有帮助

【问题讨论】:

  • 或者只创建一个辅助函数来获取它?
  • 您是否尝试过从您的帖子控制器中获取您的 cmets,而不是在您的视图中?因此,在您的帖子控制器中,抓取返回数组的帖子,然后抓取您的 cmets,调用您的 cmets_model 并将它们添加到数组中。此时,您可以将循环保持在视图中,并遍历已被抓取的子 cmets。
  • 问题是如何获取post_id并将其分配给索引
  • 在 codeigniter 中,您无法将控制器加载到视图中。你需要使用类似 HMVC bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc

标签: php codeigniter model-view-controller


【解决方案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): ?>

这就是你想要避免的,因为这样视图就会决定要显示的内容。显然,视图中会发生一些逻辑,但所有决策都应该尽可能地发生在控制器中。

【讨论】:

    【解决方案2】:

    首先,我认为您确实想要 DRY,因为 DRY 的意思是“不要重复自己”。我想你明白了这个概念,但读到你“不想干”有点令人困惑;)

    回答

    其次:在经典的 MVC 方法中(CodeIgniter 确实如此),确实可以让控制器处理模型,然后将模型(或其中的数据)传递给视图。

    现在对于如何从控制器检索您想要的所有数据有不同的概念,例如真正在控制器中读取所有内容,然后将其传递给视图,而不是仅传递“帖子”模型并让视图取出视图本身中的帖子 cmets。我认为两者都有正当理由,您可以决定使用哪一个(还有其他的!),尽管我更喜欢后一个。

    另一种方法是使用"Decorator Pattern" (see Wikipedia),它似乎仅在 CodeIgniter 中具有用户空间实现:https://github.com/ccschmitz/codeigniter-decorator

    TL;DR

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 2016-03-31
      • 2013-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多