Difference between revisions of "JController and its subclass usage overview/zh-cn"

From Joomla! Documentation

Line 35: Line 35:
  
 
JControlerLegacy默认的task是display(译者注:task是个参数,通过GET方法传递,display是JControllerLegacy中的一个方法) , 在根目录中的主控制器(controlelr)是响应task的唯一文件。我们找到com_content/content.php去查看里面的JControllerLegacy::getInstance方法,不难发现,这个方法中,模块名成为了唯一的参数。在LControllerLegacy中,使用task变量(从request中获取,一般为GET)来确定下一步,要去加载哪个类。如果在task变量中,包括一个英文的句话(点),即(.),则 点 前的为controller,点后的为task或是method。即controller.task 或 controller.method。 我们应该知道task变量,直接决定了后台执行哪个控制器(controller)中的哪个方法(method)。此例中(指task=controller.task),将加载controllers文件中的controller.class类,然后再重写task变量值为真正的task。如果task变量中没有 点(.) ,JControllerLegacy 则将加载根目录下的主控制器文件。简单来说,我们可以认为在controllers文件夹中的控制器是子控制器,只有当task中包括有 点 号时,才会调用。 在主控制器中,还指定了一个默认的视图(view),我想这点你已经注意到了。变量VIEW的值,也是由URL请求来传入的,如果URL中并未传入VIEW,那么我们在主控制器中设置的视图,将做为默认视图。一般而言,我们可以这样认为:
 
JControlerLegacy默认的task是display(译者注:task是个参数,通过GET方法传递,display是JControllerLegacy中的一个方法) , 在根目录中的主控制器(controlelr)是响应task的唯一文件。我们找到com_content/content.php去查看里面的JControllerLegacy::getInstance方法,不难发现,这个方法中,模块名成为了唯一的参数。在LControllerLegacy中,使用task变量(从request中获取,一般为GET)来确定下一步,要去加载哪个类。如果在task变量中,包括一个英文的句话(点),即(.),则 点 前的为controller,点后的为task或是method。即controller.task 或 controller.method。 我们应该知道task变量,直接决定了后台执行哪个控制器(controller)中的哪个方法(method)。此例中(指task=controller.task),将加载controllers文件中的controller.class类,然后再重写task变量值为真正的task。如果task变量中没有 点(.) ,JControllerLegacy 则将加载根目录下的主控制器文件。简单来说,我们可以认为在controllers文件夹中的控制器是子控制器,只有当task中包括有 点 号时,才会调用。 在主控制器中,还指定了一个默认的视图(view),我想这点你已经注意到了。变量VIEW的值,也是由URL请求来传入的,如果URL中并未传入VIEW,那么我们在主控制器中设置的视图,将做为默认视图。一般而言,我们可以这样认为:
如果需要调用主控制器,那么直接在URL请求中,传入view值即可。未传入view值,主控制器也将被调用,主控制器将使用默认视图。
+
* 如果需要调用主控制器,那么直接在URL请求中,传入view值即可。未传入view值,主控制器也将被调用,主控制器将使用默认视图。
 
* 如果要调用子控制器,那么需要在请求的task变量中,加入 点 号.比如CONTROLLER_NAME.CONTROLLER_METHOD。此时,将调用子控制器CONTROLLER_NAME中的CONTROLLER_METHOD方法。
 
* 如果要调用子控制器,那么需要在请求的task变量中,加入 点 号.比如CONTROLLER_NAME.CONTROLLER_METHOD。此时,将调用子控制器CONTROLLER_NAME中的CONTROLLER_METHOD方法。
  

Revision as of 01:58, 3 November 2015

Other languages:
English • ‎Nederlands • ‎español • ‎français • ‎中文(中国大陆)‎

在阅读本文前,你应该先熟悉 Joomla! MVC设计模式。

介绍

我们在Joomla! 2.5和3.x中,加入了大量的MVC优化。这使得开发变得更高轻松。在Joomla! 1.5时,只有一个Controller,那就是JController。在Joomla! 2.5中,我们除了有一个JControllerLegacy外,又添加了两个JControllerLegacy的子类,即:JControllerAdminJControllerForm。当然了,既然是三个类,使用起来肯定也不一样。我们在Joomla!的核心组件中,大量的使用了这种新的模式,比如: com_contentcom_banners

Joomla 1.5 Joomla 2.5 Joomla 3.0 及以上版本
JController JController

2.5.5以后,为了兼容性,使用JControllerLegacy

JControllerLegacy
JControllerAdmin JControllerAdmin
JControllerForm JControllerForm
JControllerBase (new MVC)

如果你查看后台管理组件com_content的核心代码,就不难发现:在两个地方出现了controller,分别是组件的根目录及controllers文件夹。在根文件夹中,存在一个名为'controller.php'的文件,它是当前组件的入口文件。在这个文件中,有一个直接继承于JControllerLegacy的类。在controller文件夹中,则存在很多个文件,这些文件均以入口关键字命名,比如:article和articles.而这些文件中的类,要么继承了JControllerAdmin,要么继承了JControllerForm

主控制器

JControlerLegacy默认的task是display(译者注:task是个参数,通过GET方法传递,display是JControllerLegacy中的一个方法) , 在根目录中的主控制器(controlelr)是响应task的唯一文件。我们找到com_content/content.php去查看里面的JControllerLegacy::getInstance方法,不难发现,这个方法中,模块名成为了唯一的参数。在LControllerLegacy中,使用task变量(从request中获取,一般为GET)来确定下一步,要去加载哪个类。如果在task变量中,包括一个英文的句话(点),即(.),则 点 前的为controller,点后的为task或是method。即controller.task 或 controller.method。 我们应该知道task变量,直接决定了后台执行哪个控制器(controller)中的哪个方法(method)。此例中(指task=controller.task),将加载controllers文件中的controller.class类,然后再重写task变量值为真正的task。如果task变量中没有 点(.) ,JControllerLegacy 则将加载根目录下的主控制器文件。简单来说,我们可以认为在controllers文件夹中的控制器是子控制器,只有当task中包括有 点 号时,才会调用。 在主控制器中,还指定了一个默认的视图(view),我想这点你已经注意到了。变量VIEW的值,也是由URL请求来传入的,如果URL中并未传入VIEW,那么我们在主控制器中设置的视图,将做为默认视图。一般而言,我们可以这样认为:

  • 如果需要调用主控制器,那么直接在URL请求中,传入view值即可。未传入view值,主控制器也将被调用,主控制器将使用默认视图。
  • 如果要调用子控制器,那么需要在请求的task变量中,加入 点 号.比如CONTROLLER_NAME.CONTROLLER_METHOD。此时,将调用子控制器CONTROLLER_NAME中的CONTROLLER_METHOD方法。

We can categorize display into two types: presenting a list of records (list view) and showing a detailed record item to the user (e.g. edit form). If we look at the articles view in com_content which displays a list of records to the user, we may notice that toolbar buttons are added according to user rights.

$JOOMLA_INSTALL/administrator/components/com_content/views/articles/view.html.php

 protected function addToolbar()
 {
   ...

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

   ...
  }

For example, to edit an article the task variable would be article.edit. This will cause the article subcontroller to be loaded and the edit method to be executed. You may have a question, this mean we will display edit form to user. That is right! In general we do that, but in Joomla! 2.5 core component, it just sets the article id to be edit in the user session and redirects it to an URL like &view=article&layout=edit. And this will be handled by master controller and edit form will be presented to user. So in this case, all display will be handled by master controller and needed views.

  • If a view name is not defined in URL, default view is used and a default task (display) will be executed. We use this to display a list of records. For example, index.php?option=com_content.
  • If a view is defined but the task is not, master controller loads specified view and executes display method. This is also used to display a list of records. For example, index.php?option=com_content&view=articles.
  • If a view is specified with a task (but not in the dot format), master controller loads the specified view and executes method specified by task. This case is used to display edit form, or to present one item of record to user. An example is index.php?option=com_content&view=article&layout=edit.

When the master controller creates a view, it normally loads a model having the same name as the view and pushes model into the view. Then the view's display method is called. Doing this, in view we can get data from model using function like $this->get("Items"). In this case, view will look for method getItems in model and execute it. Doing this, we can use one controller for display all information type in component. But many views still required. This reduces the controller class and, of course, reduces code produced by developer.

Subcontrollers

Subcontrollers will handle all CRUD tasks. For tasks such as save, delete & publish that clearly do not need a view, the subcontroller just deletes or updates records and redirects the user back to list view. In this case the user must select at least one item of record, and we usually give the name of the controller in plural form such as "articles.delete", "articles.publish_up" or "articles.publish_down". This subcontroller is generally inherited from JControllerAdmin which suppress display method by default.

The other type of CRUD, such as add or edit, at a first glance should prepare data and present the form to user. But in the core component for Joomla! 2.5, they did not do that. Looking at this kind of subcontrollers (for example ContentControllerArticle) one can see that they always are inherited from JControllerForm. But no form was presented to user in this request, it just stores item (the ID of the article) in user's session variable and redirects to master controller. As a task variable was not specified, the display method is executed as a default task.

For example: first request being processed by subcontroller may contain task=article.edit and cid[]=3. Subcontroller will create URL like "index.php?option=com_content&view=article&layout=edit" and redirect the user to master controller.