0

我正在为 Joomla 2.5 创建一个 MVC 组件,作为我构建的另一个 PHP 数据库系统的前端。我不只是将其他系统的 Web 界面包装在包装器组件中,而是构建了一个本机 Joomla 组件,该组件用于讨论其他系统类中的调用方法。

因此,我在我的一个视图中实现了一个 HTML 表单,它显然可以接受一些输入,但也可以接受文件上传。从这里组件应该将此输入发送到我的类的方法进行处理,然后将响应提供给第二个 Joomla 组件视图。

在我看来,输入的处理应该在模型中完成,并且可能接收处理后的输出也应该由模型完成。然后控制器会将模型数据提供给第二个视图?

我已经阅读了开发 MVC 组件教程,但它并没有真正让我了解它应该如何工作。谁能给我一个粗略的伪代码想法,告诉我这应该如何组合在一起,或者指向一个适当的教程或另一个做类似事情的组件的示例?

4

2 回答 2

2

简短的回答,的,您的模型应该处理项目详细信息的所有检索和保存,即它在数据库或物理文件中的行。

因此,对于更长的答案,以方式com_content工作为例。

在前端创建一篇新文章(例如通过“用户菜单”的“提交文章”项)。这是作为GET请求发送的,其值类似于:

format="html"
itemid="999"
option="com_content"
view="form"
layout="edit"

该请求如下:

  1. index.php收到请求并

  2. com_content/content.php在需要组件时调用(即 com_content 入口点)。

  3. content.phpJController通过类创建控制器。

  4. JController查看输入(即原始GET请求中发送的参数),找出它所在的组件并尝试首先加载controller.php扩展文件夹中调用的文件,然后在该文件中查找合适的类。(在这种情况下ContentController

  5. content.php然后告诉$controller对象execute()使用相关任务调用$controller->execute(JRequest::getCmd('task'));

  6. GET请求中可以看出,task在这种情况下没有设置,因此使用__default任务 ( $doTask = $this->taskMap['__default'];)在 JController 中,默认任务默认为display,除非您覆盖它。

  7. 这会导致调用类 ( ) 中的display()方法。ContentControllercom_content/controller.php

  8. 经过一些基本检查display(),然后调用parent自身的版本,即parent::display($cachable, $safeurlparams);

  9. JContoller版本display()完成所有基本工作,例如获取视图名称 ( form) 和布局 ( edit) 并使用它们加载正确的视图对象 ( ContentViewForm)。

  10. 然后它加载模型并将其作为默认模型添加到视图中。(在这种情况下,模型是contentModelForm)它根据视图名称 ( ) 和组件加载正确的模型。它是通过在它的方法中设置的,通过获取组件“内容”的名称并将“模型”附加到它。formmodel_prefixmodel_prefixJController__construct()

  11. 经过更多设置后,调用display()视图的方法ContentViewForm,这是加载模型数据的位置(如果我们正在编辑一篇文章,对模型的相同调用将根据GET包含文章中的额外参数加载现有文章标识a_id=99)。
    此时它还会加载 Article form( com_content/models/forms/article.xml) 以在tmpl文件中使用edit.php

因此,为了设置输入端,content字段来自模型(尽管对于新文章来说是一个空模型),并且字段的属性在模型匹配表单中定义。

保存对文章表单的更改采用非常相似的路径。

  1. GET请求的一部分包含您的文章 id ( a_id=99) 和将 Joomla 指向您的组件 ( option="com_content")的选项参数

  2. POST部分包含作为数组的表单 ( jform) 、正在执行的任务 ( ) 和一些其他内务处理参数。task=article.save

  3. 因此,JController此时实例化的控制器类型是ContentControllerArticlewhich extends JControllerForm(用于处理表单提交等)。
    请记住,点符号任务值的格式为[sub]controller.method

  4. 对象的save()方法ContentControllerArticle在调用它的父save()方法之前被短暂调用JControllerForm

  5. 此时,该save()方法执行检查访问权限、根据表单中定义的任何验证验证数据、然后加载模型并将表单数据传递给模型save()方法等操作。

这有帮助吗?

于 2013-09-05T07:45:31.303 回答
1

我认为您不需要使用模型来检索数据。它应该在控制器部分完成。

假设以下是一个函数是一个控制器(您可以将此函数称为任务)。

public function someFunction(){
     // retrive data from the form coming via $_POST (and consider sanitizing it)
        $data = JFactory::getApplication()->input->get('id', null, 'post');                 

      /*get model. You can call any model you want. 
       You can even call multiple models using this function
      */such as $model2 = getModel('SecondModel'); $model3 = getModel('ThirdModel');
        $model = $this->getModel('FirstModel'); //FirstModel should be an existing model
        $model->save($data);
        $formatted_data = $model->getData();

        $view=& $this->getView('OtherView','html'); //call any view you like
        $layout=JRequest::getVar('tmpl','default'); //instead of default you can use other template you prepared (such as edit...)
        $view->setLayout($layout); //bind the layout to the view
        //Pass the value to view. You can access this value in view as $this->formatted_data; later
        $view->set('formatted_data',$formatted_data);

       /*Call the view's display. 
        If you prepare other function in your view other than display, 
        you can use this function too. e.g. $view->display_report();
        But make sure you call parent::display() inside the function.
       */
       $view->display();
}
于 2013-09-05T11:21:19.730 回答