在1.5时代,只有JController这个类,但是在J2.5时代,Joomla的MVC已经很大的改进了。为了更加方便开发者开 发,Joomla提供了JController的子类。本节将就JControlelr和他的子类进行一些讨论,期望对Joomla的MVC模式有新的理 解。另外,请注意,在阅读本文之前,你需要对 Joomla1.5的MVC有所了解。否则,该文不适合你阅读。

介绍


 在 Joomla2.5中,对MVC做了很多的改进,这些改进使得开发者的工作量大大减少。在1.5版本中,只有一个控制器类(JController),在 2.5版本中增加了JControllerAdmin,JControllerForm这两个类,这个两个类都是JController的子类。每一个类 在Joomla的组件开发中都有其独特的作用,关于这些类的使用,下面是一个一般的使用方法。

我如果你分析文章组件后台的代码。 (JOOLMA_INSTAION/administrator/components/com_content),你可以看到控制器会在两个地方出现。 第一个是组件的更目录下 ,这个文件通常为controller.php.另外一个地方是controllers文件夹。controller.php这个类是主控制器类,这个类 直接派生自JController类。在controllers文件夹中的类,是子类,我个人喜欢称其为特殊控制器(非官方叫法)。特殊控制器派生自 JControllerAdmin或者JControllerForm这两个类。

主控制器


主控制器一般只处理 display任务,这个任务同时也是JController类的默认任务。打开com_content/content.php这个文件,你会发现其中 的JController::getInstance()方法只有一个参数,那就是组件的名称。在JController中,她依靠task这个变量来确 定应该加载哪一个控制器类。如果task变量中包含了点(.),那么系统就假设task变量的格式为controller.task或者 controller.method.对于我们来说,我们只需要知道task变量是用来指定控制器需要执行的任务就行了。如果task变量是 controller.task这个格式,那么系统就会加载位于controllers文件夹中的特殊控制器,然后重写task变量(去掉前面的控制器的 名称)。如果task变量中不包含点(.),JController将会加载更目录下的主控制器。在主控制器中,我们通常指定一个默认的view变量,以 此用来执行需要执行的视图。如果在请求的URL中并没有view变量,那么主控制中默认的view变量的值将被使用。所以,我们可以得到如下的结论:

用主控制器去指定一个view变量,该变量表示默认的视图。如果请求的URL中并没有view变量,那么主控制器指定的变量将被执行。

用特殊控制器去指定task变量。格式task=CONTROLLER_ANME.CONTROLLER_METHOD

在 Joomla中最常见的两种视图是:列表视图和项目详情视图。列表视图(List view)通常用来显示一个结果集。项目详情视图通常用来显示一个项目的详细情况。比喻编辑。用系统自带的文章组件作为一个例子。在文章组件中有一个叫做 articles的视图,这个视图的作用就是显示一个结果集。同时我们也注意到在视图中也添加了工具栏。这个工具栏是依据用户的权限来显示的。

protected function addToolbar()
 {
   ...
 
   if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) {
     JToolBarHelper::editList('article.edit');
   }
 
   ...
  }

 例如,如果需要编辑一篇文章,那么task变量此时的值为article.edit.这个的意思就是让系统去加载特殊控制器 (article),并且执行article控制器的edit方法。你也许有这样的一个疑问,那么是否就是说我们应该显示一个编辑的表单给用户呢?确实是 这样的,并且通常情况下我们也是这么做的。但是在Joomla2.5的核心组件中,它通过将需要编辑的文章的id设置到用户的session中,然后执行 重定向,让用户跳转到编辑页面 &view=article&layout=edit.这样设置之后,由于在URL中并没有出现task变量,因此主控器开始接手控制 了。它向用户显示一个编辑表单。所以,在这种情况下,所有的显示任务都是由主控制和需要的视图来完成的。

 如果URL中没有指定view变量,那么默认的view变量将会使用,并且系统会执行默认的任务(task),我们用这种方式来展示结果集。index.php?option=com_content

如果URL中指定了view变量,但是没有task变量,那么主控制器将会加载指定的视图并且执行display方法。这中方式通常也是用来显示结果集。index.php?option=com_content&view=articles

如 果URL中指定了view变量,并且也指定了task变量。此时的task变量不是contrller.task这种格式的时候,主控器加载指定的视图并 且执行指定的任务。这种方式通常用来展示一个编辑表单,或者展示一个项目详情。index.php?option=com_content& view=article&layout=edit

当主控制器创建一个视图的时候,它通常也会加载一个和视图同名的模型,并且将模 型的推送到视图中。然后调用视图的display方法。在视图中,我们可以使用$this->get("Items")这种类型的格式去从模型中获 得数据。$this->get("Items")它将执行模型的getItems方法。通过这种方式,我们可以用一个控制器去展现所有的信息。但是 任然要求多个视图。这些减少了控制器的类,当然,也减少了开发者需要编写的代码。

特殊控制器


特殊控制器将会处理 所有的CRUD任务。如果task是save delete,publish这些任务并不需要视图,特殊控制器只需要删除或者更新数据库中的记录,然后执行一个重定向,让页面重新到列表视图就行了。在 这种情况下,通常需要提供一个方式让用户指定其需要操作的记录,另外,我们也需要使用复数形式的控制器(articles.delete) (articles.publish_up) 或者 aritcles.publish_down.这些特殊控制器继承自JControllerAdmin。JControllerAdmin类默认不实现 display方法。(JControllerAdmin which suppress display method by default)

下 面的我们讨论一下如果执行CRUD任务中的add 或者edit.基本的想法是准备数据和表单,让用户输入或者编辑就可以实现了。但是在Joomla核心组件中,他们不这么干!分析一下 con_content组件,我们可以看到特殊控制器ContentControllerArticle是继承自JControllerForm的,他们 并不真正的向用户展示一个FORM表单,而只是储存文章的id在用户的Session中,然后重定向到主控制器。由于并没有指定task变量,因此,默认 的display方法被执行。

举例说明:第一个被特殊控制器处理的请求 可能包含了task=article.edite和cid[]=3.特殊控制器将会创建一个 URL"index.php?option=com_content&view=article&layout=edit"并且重定向用 户到主控制器。

 

作者: 樱木花道

Joomla程序员,从J1.5到J4.x始终都在做Joomla相关开发定制工作,有超过10年行业经验,国内Joomla扩展开发商ZMAX团队的核心成员

作者网站:ZMAX程序人

评论 (0)

  • 最新在前
  • 最佳在前