本节将重点介绍视图和视图用到的模版布局之间的关系。我们需要明白,一个视图可以有多个layout(布局),对于大多数的有关界面上的修改,我们都是在布局中完成的。
在第五节中的视图类中,解决了500错误。组件也成功执行了。下面我们让组件输出点东西。
视图输出内容
修改views\guestbook\view.html.php文件内容如下:
// 禁止直接访问这个文件 defined('_JEXEC') or die ('you can not access this file!'); jimport('joomla.application.component.view'); /** * Guestbook组件的HTML视图类 */ class GuestBookViewGuestBook extends JView { function __construct() { parent::__construct(); } function display($tpl = null) { echo "I am from 视图类的display 函数.";//增加一个输出语句 parent::display($tpl); } }
在前台的执行结果为:
在这里需要思考了:是谁实例化了GuestBookViewGuestBook这个类?又是谁调用display这个函数?
在 前面一直强调joomla中命名是十分重要了。在这里就体现出来了。如果将GuestBookViewGuestBook这个类的名称换一个别的名字,组 件会成功执行吗?答案是否定的。为什么呢?因为我们的代码依赖于命名规则。Joomla系统会自动加载按照一定命名规则命名的类和函数。
JoomlaMVC中,控制器在执行display方法的时候会自动实例化与之同名的视图类和模型类。那么什么叫与之同名呢?
在本例中控制器的类名为GuestBookController
视图的类名为:GuestBookViewGuestBook
很明显Joomla认为GuestBookController 和 GuestBookViewGuestBook是同名的类。一个是控制器,一个是于控制器对应的同名的视图类。至于为什么会是这样。在后面会解释。暂且不管它
以上表述有误,于2013-10-27更改:
很明显,GuestBookController类和GuestBookViewGuestBook并不是同名的类,那么为什么它也能正确执行呢?这个问题的答案就是,当你指定了视图的时候,joomla的控制器类会自动实例化于视图同名的模型类。(你在下面的章节中会看到),但是如果你没有指定视图的时候(index.php?option=com_guestbook,并没有指定view参数),joomla控制器将会使用默认机制。默认的视图就是组件的名称,也就是GuestBookViewGuestBook。这就是为什么上面的代码能正确执行的原因。
于2014-11-06日改:对于display方法执行的时候做的事情,正确的理解应该是这样的。在执行请求的时候,系统会检测view变量。如果view变量为空,那么view变量自动赋值为组件的名称。view变量确定了,那么视图就确定了。至于说自动实例化与之同名的视图类和模型类,这是说系统会实例化GuestBookViewGuestBook 和 GuestBookModelGuestBook这两个类
在Joomla中视图类主要的任务有两个:
- 从模型中获取数据(调用相应的函数)
- 将获取的数据注入到要显示的模版中
布局输出内容
下面修改一下 views\guestbook\tmpl\default.php文件的内容如下:
I am from guestbook\tmpl\default.php
再次在浏览器地址栏输入:http://localhost/j25/index.php?option=com_guestbook.执行结果如下:
这说明default.php文件也被执行了。
当views下的视图文件被执行的时候,系统默认情况下会查找tmpl下default.php文件,并将数据传入到这个模版文件。
继续修改代码:
view.html.php文件:
// 禁止直接访问这个文件 defined('_JEXEC') or die ('you can not access this file!'); jimport('joomla.application.component.view'); /** * Guestbook组件的HTML视图类 */ class GuestBookViewGuestBook extends JView { public $msg0 = "welcome to zmax99.com!"; function __construct() { parent::__construct(); } function display($tpl = null) { $msg1 = "Hello World"; $this->assignRef( 'msg1', $msg1 ); parent::display($tpl); } }
default.php文件:
I am from guestbook\tmpl\default.php
echo $this->msg0."
"; echo $this->msg1."
";
输出的结果:
输出的结果说明了一下几个问题;
- 系统是自动加载default.php文件的(按照某种约定)
- default.php文件中的$this和view.html.php文件中的$this是同一个对象。因为通过他们都可以访问类的msg0成员
- msg1在default.php中也可以通过$this进行访问。
重点解释一下为什么msg1能够在default.php中通过$this来访问。这是因为 $this->assignRef( 'msg1', $msg1 );这个函数的作用。这个函数将$msg1这个变量注入到模版中。好让default.php中的$this来访问。
感觉越理越乱。总结一下,上面代码的执行流程是:控制器类实例化与之同名的视图类(view.html.php文件)。视图类获取数据,将输入注入到模版(defaullt.php文件)。在view.html.php中可以使用assignRef来注入数据到模版。使得在模版中访问数据更加方便简洁。
在写这篇文章的时候感觉非常的吃力,看来自己对joomla的了解还有待加深!
于2014-02-23添加:关于组件的详细执行过程,请参阅\libraries\joomla\application\component\controlelr.php文件,这个文件详细的说明了joomla是如何寻找要加载的文件的。
于2014-11-06日改:理论上display($tp=NULL)这个参数决定了视图显示哪一个layout.这个本人没有尝试
评论 (0)