在CodeIgniter的视图中包括视图的最佳方法


67

我正在启动一个大型代码点火器项目,并想尝试为内容片段(如可能在不同页面/控制器上显示的数据循环)创建一些可重用的“迷你”视图。

从主控制器的视图中调用视图更好吗?如果是这样,怎么办?还是应该从控制器调用“迷你视图”,然后将视图的代码传递给主视图?


1
与此相似的问题(Laravel) - stackoverflow.com/questions/17227969
罗宾汉

Answers:


117

其他视图中的视图称为嵌套视图。在CodeIgniter中包括嵌套视图的方法有两种:

1.将嵌套视图加载到控制器内部

预先加载视图并传递到另一个视图。首先将其放在控制器中:

<?php
// the "TRUE" argument tells it to return the content, rather than display it immediately
$data['menu'] = $this->load->view('menu', NULL, TRUE);
$this->load->view ('home', $data);
?>

然后<?=$menu?>在您希望菜单出现的位置进入视图。

2.“从内部”加载视图

首先将其放在控制器中:

<?php
  $this->load->view('home');
?>

然后将其放在/application/views/home.php视图中:

<?php $this->view('menu'); ?>

<p>Other home content...</p>

关于最佳方法,我更喜欢第一种方法,而不是第二种方法,因为通过使用第一种方法,我不必混淆代码,这与include php不同。尽管间接两者都相同,但是第一种方法比第二种方法更清晰,更干净!


我认为无需提前加载视图并传递给其他视图。请参阅我的解决方案
Rahul Chipad 2013年

1
@RahulChipad,您没有注意到该注释:“ TRUE”参数告诉它返回内容,而不是立即显示它,这意味着即使预先加载它也完全不会影响
Sandip 2013年

3
警告:以这种方式(使用TRUE参数)传递视图时,会将所有视图内容转换为字符串。这在大多数情况下都有效,但是一旦您拥有大量数据,或者当您传递数组或JSON时,这将中断。
CodeGodie 2015年

2
我不喜欢方法1,因为在home视图中永远不会正确接收$menu...如果您要查看的话home,您将不知道它$menu是从哪里来的
dsdsdsdsd

2
第二种

18

老实说,我更喜欢这样做,首先要有模板视图,然后再从控制器中加载必要的数据,这意味着重复代码要少得多,并且比从视图中加载视图更好地遵循了DRY概念。特别是用于页眉,页脚和菜单之类的东西。

因此,我的模板视图如下所示:

template.php

$this->load->view('header',$title);
$this->load->view('sidebar',$sidebar_content);
$this->load->view('main_content',$main_content);
$this->load->view('footer');

然后在我的控制器中,将所需的数据传递给模板,如下所示:

$data['title'] = 'Home Page';
$data['sidebar_content']='pages/standard_sidebar';
$data['main_content'] ='pages/my_home_page'; 
$this->load->view('template',$data);

这样做有很多好处。首先是我可以有多个模板,例如,我有两个主要模板,一个用于没有侧边栏的完整页面视图,一个用于有侧边栏的页面,我还调用了if语句来确定要包含的标头,常规菜单或其中带有管理菜单的菜单。

是的,我可以在每个主视图页面中包含页眉,侧边栏和页脚,但这最终导致了大量重复代码。例如,如果我希望我的所有页面都有新内容,以及其他一些小片段,将会发生什么?使用模板,我将代码段添加到适当的模板中,并且已经完成。走另一条路线,我会找到每个页面并在其中添加代码段视图,这相当于在我看来页面中包含CSS,这很浪费,而且最终无法维护。


1
我喜欢您的技术,但我不太了解其他方法如何增加编码工作量。举例来说,如果我想在标题视图中添加语言栏,则只需编辑标题视图即可。我想念什么吗?顺便说一句,我是一位旧时编码员,对CodeIgniter来说是全新的。
itsols 2015年

它们不会像增加重复代码那样增加编码工作量。看上面的代码。如果我还没有创建模板,那么我将为控制器中的每个页面调用前4行。最重要的是模块化和易于包含/排除。在一个非常基本的站点上,所有页面都具有相同的元素,这没什么大不了的,甚至根本不值得付出额外的努力。在页面变化很大的复杂站点上,可以避免很多麻烦和重复。
里克·卡尔德

这实际上与@sandip的答案的方法2不同吗?
dsdsdsdsd 2016年

我的答案给出了相同代码的另一种观点,并展示了拆分成模板的好处。注入的方法是相同的,整体视图甚至不紧密。3岁的答案,两个人以不同的观点给出相同的代码真的重要吗?
Rick Calder

如何将$ data传递给标头?假设我想将更多内容传递给标头,而不仅仅是$ title
Lucas Bustamante

8

方法1

我在视图中使用此方法在需要的地方插入包含视图

$this->load->view('include/include_view');


方法2

或在控制器中,您可以加载的视图不仅是这样的:

$this->load->view('header_view');
$this->load->view('list_view');
$this->load->view('footer_view');

没有一种方法比另一种方法更好,这取决于您是否必须传递一些数据(在这种情况下,请使用method2),或者是否要在主视图的特定部分中包含视图(在这种情况下,最好使用method1) )


方法3

通过主视图将数据传递到包含视图

进入您的控制器:

$data['title'] = "Title";
$this->load->view('main_view',$data);

在你看来

$data2['title'] = $title;
$this->load->view('include/include_view',$data2);

如果要将整个数据传递到包含视图,则可以通过以下方式进行:在控制器中:

$data['nestedView']['title'] = 'title';

在你看来

$this->load->view('includes/included_view', $nestedView);

我将要传递数据,但是方法一似乎是一个更好的主意。只需找出如何将数据传递给它即可。
David

好吧,您可以在这种模式下传递数据:$ this-> load-> view('include / include_view',$ data); 但是问题是,在控制器中,您必须将数据传递到主控制器,并且在主控制器中,必须将数据传递到包含视图,这是很长的路要走,但如果需要,您可以
Alessandro Minoccheri

有没有办法传递整个数据?
大卫

4

这是在视图中包含视图的一种简单方法。不需要预先加载视图。只需将视图路径传递给其他视图。

在您的控制器中使用以下命令:

$data['middle'] = 'includeFolder/include_template_view';  //the view you want to include
$this->load->view('main_template_view',$data);  //load your main view

在main_template_view中,您可以包含其他视图:

$this->load->view($middle);

1

我认为为了更有效地解决此问题,我这样做了:

您使用名称(例如,common_helpers.php,下划线很重要)创建一个新的帮助程序(在应用程序/帮助程序中)。在此文件中,您将所有功能(例如,共同构建html)放在一起。

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

    function getHead(){
    require_once(APPPATH."views/common/head.php");
    }   

    function getScripts(){
    require_once(APPPATH."views/common/scripts.php");
    }

    function getFooter(){
    require_once(APPPATH."views/common/footer.php");
    }

在您的控制器中,您只能调用一个关于MVC的视图,并从您的自定义帮助器中调用函数。

class Hello extends CI_Controller {

   public function index(){
       $this->load->helper('common');
       $this->load->view('index');   
   }

}

-1

在控制器中

控制者

<?php
    public function view($page = NULL)
        {
          if ( ! file_exists(APPPATH.'views/pages/'.$page.'.php'))
        {
                 $data['title'] = ucfirst($page); // Capitalize the first letter
                // Whoops, we don't have a page for that
                show_404();

        }

        $data= array(''); 
        $data['title'] = ucfirst($page); // Capitalize the first letter 
         $data['page_layout']='pages/'.$page;    
         $this->load->view('page_layout', $data);
        }
?>

在“视图”文件夹中,创建一个名为page_layout.php的页面。

page_layout.php

//This is where you set the layout to call any view through a variable called $page_layout declared in the controller//

 <?php
     $this->load->view('header');
     $this->view($page_layout);
     $this->load->view('footer');
  ?>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.