我的页面上有一个菜单,每个页面都会加载。菜单数据通过模型从数据库中获取。我的第一个想法是从控制器调用模型,然后将其传递到每个页面上的视图。但这会导致"凌乱"代码,如果我忘记将菜单数据传递给视图,将导致一个丑陋的错误(或者只是没有菜单项)。
所以我提出了通过帮助器获取菜单项的解决方案,然后从视图中调用辅助函数。它更有意义,因为我只在一个地方(菜单视图)中有代码。
我的观点以这种方式设置:控制器调用"页面"视图然后加载标题视图,菜单视图,相应的内容视图,最后加载页脚视图。帮助器只从一个地方调用,即菜单视图。
通常情况下,您甚至无法从帮助程序加载模型,但我使用$ i = get_instance()进行了解决方法;然后通过该实例加载模型; $ I->负载>模型()
我觉得这不是可行的方法,但还有更好的方法吗?
编辑:以更好的方式表达:
我想: 查看 - >获取数据 - >显示
不: 控制器 - >获取数据 - >传递给视图 - >显示
我不确定那是不是"好的"这样做,因为它完全忽视了MVC模型。
答案 0 :(得分:2)
所以我找到了一个切割n-paste的快速示例(在这种情况下,我有一个名为login
自动加载的模型,但你当然可以手动执行此操作)
在档案core\MY_Controller.php
class Admin_Controller extends CI_Controller
{
protected $login_ok;
public function __construct()
{
parent::__construct();
/* --- Check if user is logged in --- */
$this->config->load('adldap', TRUE);
$data->login_ok = $this->login->check_login(TRUE);
$this->load->vars($data);
}
}
如果您随后使用此扩展控制器。您可以在视图中看到$login_ok
。
通过这种方式,您可以确保始终准备好所需的变量,并且只需将代码编写在一个地方
答案 1 :(得分:1)
我认为解决方案比你想象的要容易。
如果现在你正在帮助你做这样的事情:
create_menu()
{
$menu_items = $this->db->query('')->result();
// creating the menu here
}
你可以改变函数来接受这样的输入,并且仍然遵循MVC模式。
<强>辅助强>
create_menu($input)
{
$menu_items = $input;
// creating the menu here
}
<强>型号:强>
get_menu_data()
{
$menu_items = $this->db->query('')->result();
}
这有意义吗?
修改强>
这是我在其中一个项目上做到的方式:
我扩展了我的标准控制器。在该控制器的构造函数中,我调用了模型并获取了数据:
$this->menu_items = $this->some_model->get_menu_items();
在视图中nav.php
:
if(!empty($this->subnav_item))
{
// Generate menu
}
这样MVC完好无损,但我不必担心传递变量。
编辑2
如何扩展标准控制器:
在MY_Controller.php
application/core
class MY_Controller extends CI_Controller {
public $menu_items = '';
function __construct()
{
parent::__construct();
$this->load->model('some_model_that_you_always_use');
$this->load->library('some_library_that_you_always_use');
$this->menu_items = $this->some_model->get_menu_items();
}
}
当您创建新控制器时,您可以像这样扩展MY_Controller
而不是CI_Controller
:
class Something extends MY_Controller {
}
答案 2 :(得分:1)
请记住,MVC模式没有任何内容禁止View直接联系模型。这只是一个与CodeIgniter相似的惯例。
我建议在这种情况下,菜单视图应直接从菜单模型中加载菜单数据。