黑马程序员技术交流社区

标题: 【上海校区】Yii框架的视图层实现 [打印本页]

作者: 梦缠绕的时候    时间: 2019-2-19 11:07
标题: 【上海校区】Yii框架的视图层实现
如果你想看看 Yii 框架的视图实现过程,请继续向下;如果你想看看胖子的碎碎念,请直接拉到文章最后;如果你只是路过,那也路过留名吧^_^。
Martin Flower 在《企业应用架构模式》中提到 MVC 模式的关键点在于两个分离:从模型中分离视图和从视图中分离控制器。视图的表现在很大程度上决定了此模式的使用,以及框架对 MVC 模式的各个层级的分离水平。 Yii 框架是一个基于 MVC 模式的框架,它在视图这块做了很多的工作,很清晰的实现了视图的功能。
Yii 框架的视图是一个包含了主要的用户交互元素的 PHP 脚本。每个视图有一个名字,当渲染( render )时,名字会被用于识别视图脚本文件。视图的名称与其视图脚本名称是一样的。例如:视图 edit 的名称出自一个名为 edit.php 的脚本文件。要渲染时,需通过传递视图的名称调用 CController::render()。这个方法将在 “protected/views/控制器 ID” 目录下寻找对应的视图文件,其寻找方法为 getViewFile。这里的 protected/views 只是默认的存储位置,我们可以通过 Yii::app()->setViewPath 方法改变此路径。
在视图脚本内部,我们可以通过 $this 来访问控制器实例。同时,我们也可以在视图里以“$this->属性名”的方式获取控制器的任何属性,这种调用方式是通过实现__get魔法方法实现的。
一次较为完整的视图渲染过程在 CController 类的 render 函数中体现得淋漓尽致。当控制器中从模型(model)中拿到数据后,一般会执行 render() 方法创建视图,其大概过程如下:
在渲染视图的时候,如果参数中有传递对应的值,会执行 processOutput() 方法,此方法一般在渲染视图结束时才会调用,它实现了三个过程:
在 CController 类中对视图的渲染除了上面的render方法外,还有其它多种方法:
对于不同的页面中共用的内容,虽然可以通过 renderPartial 方法渲染部分页面视图,但是必然存在对于数据部分的重复,因为这些视图都需要调用控制提供的数据,从而产生耦合。因此 Yii 框架 提供了另一个独立的视图部件,官方称之为 Widget (小物件?小挂件?)。
小物件是 CWidget 或其子类的实例。它是一个主要用于表现数据的组件。小物件通常内嵌于一个视图来产生一些复杂而独立的用户界面。也算是一种界面的独立和松耦合的设计。如我们做WEB应用时常用的列表,翻页,日历等。这些 Widget 增加了界面的复用度,减少了代码量。
与前面视图部分不同的是,它没有布局文件支持,并且 Widget 视图中的 $this 指向 Widget 实例而不是控制器实例,这里实现了与控制器的分离。如果要实现一个自定义的 Widget ,我们仅需要继承 CWidget 并覆盖其 init() 和 run() 方法,可以定义一个新的 Widget 。
我们在视图中通过 $this->widget() 或 $this->beginWidget() 和 $this->endWidget() 调用 Widget,两者的区别在于第二个方法可以在显示的过程中添加 html 内容。添加内容的位置在 init() 方法和 run() 方法输出的内容之间。
除了布局、Widget 外, Yii 框架实现系统级的视图,用来显示 Yii 的错误和日志信息。
系统视图的命名遵从了一些规则。比如像“errorXXX”这样的名称就是用于渲染展示错误号 XXX 的 CHttpException 的视图。在 framework/views 下, Yii 提供了一系列默认的系统视图. 我们可以通过在 protected/views/system 下创建同名视图文件进行自定义。系统默认的 exception 视图非常赞,结合 Yii 本身的 traces 机制,当抛出异常或出错时就会很详细的定位出问题的代码所在。
以上只是胖子阅读 Yii 框架源码的笔记。结合《企业应用架构模式》这本书的内容,如页面控制器、前端控制器、活动记录等,胖子发现对框架的实现有更深入的理解。一方面印证了书上的理论,一方面为实现过程的原理找到了出处。不晓得 Yii 框架的作者是否对此书也有精读,或者是经验的积累?


作者: 不二晨    时间: 2019-2-20 09:25
今天也要加油鸭




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2