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

From Joomla! Documentation

(Created page with "* 如果在URL中未设置view,那么view将被设置为主控制器的默认变量,并执行默认的display(即:task="display")方法。")
(Created page with "* 如果定义了view,但是task没有定义,那么主控制器将加载传入的view,并执行特定VIEW中的display方法。这种方法同样适用于显示数据列...")
Line 61: Line 61:
  
 
* 如果在URL中未设置view,那么view将被设置为主控制器的默认变量,并执行默认的display(即:task="display")方法。
 
* 如果在URL中未设置view,那么view将被设置为主控制器的默认变量,并执行默认的display(即:task="display")方法。
* 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.
+
* 如果定义了view,但是task没有定义,那么主控制器将加载传入的view,并执行特定VIEW中的display方法。这种方法同样适用于显示数据列表,比如: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.
 
* 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.
  

Revision as of 02:15, 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方法。

我们可以把显示(display)总结为两种:1.数据列表,即显示一页数据。2.某条数据的详情(比如:"edit form")。我们用普通后台用户登陆后,打开文章管理,根据用户的不同,后台显示的按钮也不同。

$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');
   }

   ...
  }

比如说:当我们编辑一篇文章时,task变量的值应该设置为article.edit。这将加载article子类中的edit方法。这时候,你可能要问了,这意味着我们将为用户显示一个编辑的表单。是的,的确如此!一般情况下,我们的确需要这样做,但是在joomla! 2.5的核心组件中,我们需要做的是,将要编辑的article id 存入session,同时,将URL指向为&view=article&layout=edit就可以了。此URL将直接交给主控制器处理, 同时编辑表单也会显示给用户。在这个实例中,我们发现,所以的显示(display)都会按view变的值来交给主控制器处理。

  • 如果在URL中未设置view,那么view将被设置为主控制器的默认变量,并执行默认的display(即:task="display")方法。
  • 如果定义了view,但是task没有定义,那么主控制器将加载传入的view,并执行特定VIEW中的display方法。这种方法同样适用于显示数据列表,比如: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.