热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Yii框架的视图层实现

如果你想看看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() 方法创建视图,其大概过程如下:

  1. 执行预留的 beforeRender 钩子。
  2. 查找渲染局部内容 $output,实际上这里是一个部分视图渲染的过程,它包括获取视图文件路径,渲染视图文件,处理输出三个部分。在渲染的过程中,通过 PHP 中的 extract() 方法把数组中将变量导入到当前的符号表,直接 require 视图文件,从而合并数据和表现。
  3. 如果存在布局,则将得到的内容放入以 content 为下标的的数组传递给父类的 renderFile() 方法中,重复执行渲染视图的过程。在布局中执行 ,输出局部内容$output,实现了局部和布局视图的合并。为了实现多级布局,在布局中还可以通过控制器的视图装饰方法加载。
  4. 执行预留的 afterRender 钩子。

在渲染视图的时候,如果参数中有传递对应的值,会执行 processOutput() 方法,此方法一般在渲染视图结束时才会调用,它实现了三个过程:

  1. 注册客户端脚本,具体由 ClientScript 组件管理。
  2. 如果存在,则执行动态内容输出。
  3. 页面内容 base64_encode 加密,如果存在 zlib 扩展,则会先压缩。

在 CController 类中对视图的渲染除了上面的render方法外,还有其它多种方法:

  • render方法: 和布局一起渲染 render($view,$data=null,$return=false)
  • renderPartial方法: 仅渲染视图内容,或者是渲染部分页面内容。它与 render() 方法的不同是它不会渲染布局,并且在 render() 方法中也会调用此方法。 renderPartial($view,$data=null,$return=false,$processOutput=false)
  • renderText方法:渲染静态内容和布局。renderText($text,$return=false)
  • renderDynamic方法:通过回调函数渲染动态内容,通常我们会在模板文件中中调用此方法。renderDynamic($callback)->renderDynamicInternal($callback,$params)
  • renderClip方法:渲染显示 CClipWidget 生成的内容,此处需要指定名字。renderClip($name,$params=array(),$return=false)

对于不同的页面中共用的内容,虽然可以通过 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 框架的作者是否对此书也有精读,或者是经验的积累?

参考资料: http://www.yiiframework.com/doc/guide/1.1/en/basics.view


推荐阅读
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了一种处理AJAX操作授权过期的全局方式,以解决Asp.net MVC中Session过期异常的问题。同时还介绍了基于WebImage的图片上传工具类。详细内容请参考链接:https://www.cnblogs.com/starluck/p/8284949.html ... [详细]
  • Todayatworksomeonetriedtoconvincemethat:今天在工作中有人试图说服我:{$obj->getTableInfo()}isfine ... [详细]
author-avatar
mobiledu2502903113
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有