jobeet第四天:控制器和视图

*这一系列文章来源于Fabien Potencier,基于Symfony1.4编写的Jobeet Tutirual

在昨天的内容中,我们已经生成了JobController控制器,那么我们今天就来对JobController控制器进行自定义操作。Symfony自动生成的JobController控制器已经有了我们所需要的大部分代码了:

  • 列表(list)页面
  • 创建(new create)页面
  • 编辑(edit update)页面
  • 删除(delete)页面

现在我们在已有代码的基础上进行重构,让Jobeet的页面更加接近Jobeet的模型

MVC架构

对于Web开发来说,现在最常见的代码组织方式就是使用MVC设计模式。简而言之,MVC设计模式定义了一种组织和编写代码的规范,这样会使得你的代码和结构看起来更加地合理。MVC模式把代码分为三个层次:

  • Model层:定义业务逻辑(数据库操作也属于这层)。我们已经知道了在Symfony中,所有和Model层相关的类都放在Entity/目录下。
  • View层:与用户交互的图形界面(模板引擎属于这个层)。Symfony 2.3.2View层使用的模板引擎主要是TwigSymfony中的视图文件被放在各个Resources/views/目录下,我们待会就来介绍它。
  • Controller层:它通过Model层来获取数据,然后对数据进行处理后把结果渲染到View层并返回给客户端(浏览器)。在教程的第一天中我们就简单地介绍了怎么样通过Symfony来访问页面,我们已经看到所有的请求都被前端控制器(front controller)给管理起来了(app.phpapp_dev.php),而前端控制器其实把真正的工作交给action来处理。

布局

如果你有仔细观察Jobeet的模型,你可能会注意到它们的每个页面看起来都很相似。我们都知道,不管是PHP代码还是HTML代码,重复的代码给人的感觉就是很差,因此我们需要找到一个方法来提取重复的代码,这样做我们的程序才会更加简洁和容易维护。

我们有一种解决方法是,我们可以先定义出页面的headerfooter,然后把它们包含在每个页面中。另一种更好的办法则是使用一种设计模式来解决问题:装饰者模式装饰者模式解决问题的方式是:即先把一个子模板渲染完成后再把它放到一个全局的模板中去,而那个全局的模板叫做布局(layout)

Symfony2中并没有提供默认的布局,所以我们需要来创建一个布局来装饰其它的子页面模板。

我们在src/Ibw/JobeetBundle/Resources/views/目录下创建一个新文件layout.html.twig,它的代码如下:

 

Twig区块(Blocks

TwigSymfony默认的模板引擎,你可以像我们在上面的代码中一样定义区块(blocks)。在Twigblock中,我们可以给它们定义默认的内容(比如上面的title block)。待会我们将会看到如何在子模板中替换block中默认的内容或者是继承block中的内容。

现在我们想要使用layout的话,我们还需要去编辑子模板(src/Ibw/JobeetBundle/Resources/views/Job/目录下的indexeditnewshow)去继承layout并重写(overwrite)layout中的block content。子模板的结构就像下面那样:

 

StylesheetsJavascripts和图片

我们的教程不是讲授怎样进行Web设计,所以这里已经准备好了所有需要使用到的资源。点击这里下载图片,然后把这些图片放在src/Ibw/JobeetBundle/Resources/public/images/目录下,点击这里下载css文件,然后把css文件放在src/Ibw/JobeetBundle/Resources/public/css/目录下。

现在运行下面的命令:

上面的命令为了是告诉Symfonycss图片资源作为公用(外部可以访问到)的。

css文件夹中,我们可以看到有四个文件:admin.cssjob.cssjobs.cssmain.cssmain.css需要被所有的Jobeet页面使用,所以我们把它放在layout中的stylesheet twig block里。剩下的其它三个css文件我们在需要用到它们的时侯才把它们加入到页面中。

为了能够在模板中加入新的css文件,我们需要重写stylesheet block中的内容,但需要先调用父block,这样才不会把main.css给覆盖掉(看代码就明白了)。

 

 

Job首页Action

一个action就对应着一个控制器中的一个操作。简而言之,action就是一个方法。对于访问Job(职位)首页来说,此时的控制器是JobController,而对应的actionindexAction()indexAction()会取出数据库中所有的Job数据。

我们来仔细看看上面的代码:在indexAction()方法中得到了一个Doctrine实体管理对象(entity manager object),这个对象会负责把数据持久化到数据库或者把数据从数据库中取出。Repository则生成一个查询去检索数据库中的Job数据,它会返回一个Job类型的Doctrine ArrayColletion对象,然后把这个对象传递给模板(视图)。

Job首页模板

index.html.twig模板有一个显示所有Job数据的HTML表格。下面是它的代码:

我们来清除一些不需要显示出来的列(columns)。用下面的代码替换掉twig block content

04-01

Job页面模板

现在我们来自定义Job页面的模板。打开show.html.twig,用下面的代码替换它:

Day-4-individual-job

Job页面的Action

Job页面是通过show这个动作生成的,showAction()被定义在JobController

 

就像在indexAction()中一样,IbwJobeetBundle repository是用来检索一个指定的Job数据,但这次使用的是find()方法。find()方法的参数是能一个够唯一标识Job的标识符,即主键。在下面的内容中我们会探索showAction()是怎么样得到Job数据的主键$id的值。

如果用户需要访问的Job页面不存在,throw $this->createNotFoundException()将会把我们重定向到404页面

异常(excpetions)在production环境和devlopment环境下显示的页面会不同。

Day-4-error1 Day-4-error2

今天我们就先到这啦,明天我们来将会讲解路由(routing)功能。

 

原文链接:http://www.intelligentbee.com/blog/2013/08/10/symfony2-jobeet-day-4-the-controller-and-the-view/

发表评论