12 分钟阅读时间 (2428 字)

《Joomla! 3.0 扩展开发系列:更多功能》

Joomla! 3.0 Extension Development Series: More Functionality

Joomla! 3.x 开发系列已经稳步进行了几个月。到这个时候,你应该对扩展开发的基本知识有相当好的把握,希望你已经开始编写自己的代码。本文将继续扩展你在代码和 Bootstrap 在开发中的应用方面的知识。不要忘记回顾本系列的过往文章。

第 0 步:制作咖啡

到目前为止,我们已经一起花费了几篇文章来构建这个组件。我相信在这个阶段,你已经意识到了第一步。在开始编写代码或构建下一阶段的过程之前,继续我们从一开始就养成的习惯是很重要的。找到你最喜欢的杯子,用你选择的液体平静感填满它。如果你是新手,我建议回顾之前的文章,从开始的地方开始,逐步完成本系列的现有内容。我会在这里等你。

好!欢迎回来。在本文中,我们将查看 Lendr 中涉及的一些其他功能。你会发现我在之前为空的许多文件中添加了更多的代码。而不是花时间审查每一个,我将仅关注引入新功能或概念的区域。你应该能够根据之前的文章轻松理解代码。现在,我们将通过编写 Lendr 组件所需的各个模态窗口来继续我们的系列。

第 1 步:创建模态窗口

在本文中,我们采取了一种更为轻松的方法,专注于一些额外的功能和细节工作。首先,您会注意到我们增加了更多的模态窗口。我们以相同的方式(利用Bootstrap技术)制作了所有模态窗口。为了提供更多细节,我将解释两种选项,然后详细说明我们选择的选项。首先,您可以通过AJAX加载视图和布局,使用典型的Joomla方法。虽然使用模态窗口加载整个视图文件,但在点击按钮或链接时,这已经成为了Joomla加载模态窗口的标准方法(您可以将其想象成iframe)。第二种方法是在页面初始加载时将模态窗口的详细信息加载到页面中。然而,在页面加载时,模态窗口(本质上,包含视图的div)默认隐藏,直到被链接或按钮点击激活。

我选择在Lendr中使用第二种模态加载方法,原因有几个。通过在页面加载时将模态div添加到页面中但保持其隐藏,这使所有页面加载速度都集中在初始页面加载上。虽然这可能会让您认为页面将更慢地加载,但这只是一个微小的增加。另一方面,当点击按钮或链接时,由于HTML已经在页面中加载,因此模态窗口会立即出现。这往往使页面感觉加载速度极快。虽然这可能是一种个人偏好,但我注意到了这一点,因此更喜欢。选择这种模态加载方法的第二个原因是,模态中只有几个数据字段。因为请求的数据很少,所以动态地将这些变量分配给模态并不困难,而不是通过AJAX请求整个页面。这同样是一种关于速度的个人偏好。

让我们看看在页面中包含模态所需的代码行。首先,我们将查看“容器”视图的html.php文件。这也可以被认为是我们要加载的模态窗口的父视图。

html.php
_lend.php
book.php

我将继续使用这段代码在Lendr中重复加载模态窗口。您会注意到我将调用两种不同的方法来加载模态窗口。一种是直接加载模态窗口(这是在模态窗口不需要额外数据时发生的情况),另一种是使用javascript调用加载模态窗口(当我想在显示之前向模态窗口添加变量时,我将使用第二种方法)。

您可以在我们的Github仓库中找到其余的模态文件(结构与上述相似)。

第2步:编写借阅和归还功能

现在我们已经加载并显示了一些模态窗口,我们想要通过使用这些模态窗口为Lendr添加功能。首先,我们将查看实际的借阅和归还的核心过程。如果您想知道,我们不会在Lendr中构建任何高级跟踪或监控系统(这可能是稍后我会更详细地查看的事情,如果有人要求的话)。在Lendr中,我们只是让您借阅一本书,并在收到它时将其标记为已归还。与借阅和归还过程相关的有几个文件。我们将在下面更详细地查看每个文件。

控制器

首先,我们将回顾lend.php控制器文件,该文件是借阅和归还的主要控制器。

joomla_root/components/com_lendr/controllers/lend.php

<div class="modal-body">
  <div class="row-fluid">
    <form id="reviewForm">
      <input class="span12" type="text" name="title" placeholder="" />
      <textarea class="span12" placeholder="" name="review" rows="10"></textarea>
      <input type="hidden" name="user_id" value="" />
      <input type="hidden" name="view" value="review" /> 
      <input type="hidden" name="book_id" value="" />
      <input type="hidden" name="model" value="review" />
      <input type="hidden" name="item" value="review" />
      <input type="hidden" name="table" value="review" />
    </form>
  </div>
</div>
<div class="modal-footer"> </div>

模型

在控制器中,我们再次执行单个任务(执行),在这个任务中,我们将数据和请求直接传递给Book模型,该模型将处理借阅功能调用。下面是Book模型中位于lend函数的位置。

joomla_root/components/com_lendr/models/book.php

public function lend($data = null)
  {
    $data = isset($data) ? $data : JRequest::get('post');
 
    if (isset($data['lend']) && $data['lend']==1)
    {
      $date = date("Y-m-d H:i:s");
 
      $data['lent'] = 1;
      $data['lent_date'] = $date;
      $data['lent_uid'] = $data['borrower_id'];
 
      $waitlistData = array('waitlist_id'=> $data['waitlist_id'], 'fulfilled' => 1, 'fulfilled_time' => $date, 'table' => 'Waitlist');
      $waitlistModel = new LendrModelsWaitlist();
      $waitlistModel->store($waitlistData);
    } else {
      $data['lent'] = 0;
      $data['lent_date'] = NULL;
      $data['lent_uid'] = NULL;
    }
    
    $row = parent::store($data);    
    
    return $row;
 
  }

在这个函数中,您会注意到我们同时处理了借阅和归还。请注意,当一本书成功借出时,我们也会将相应的等待列表项标记为已满足。

JavaScript

这是与借阅和归还相关联的JavaScript函数。正如我之前提到的,我正在创建一个函数来首先加载模态框(这样我就可以将变量注入到模态窗口中)。第二个函数用于实际借阅书籍。我正在使用jQuery AJAX调用来将表单数据传递给上面列出的借阅控制器。如果控制器/模型执行成功,则关闭模态窗口。

joomla_root/components/com_lendr/assets/js/lendr.js

function loadLendModal(book_id, borrower_id, borrower, waitlist_id)
{
  jQuery("#lendBookModal").modal('show');
  jQuery('#borrower_name').html(borrower);
  jQuery("#book_id").val(book_id);
  jQuery("#borrower_id").val(borrower_id);
  jQuery("#waitlist_id").val(waitlist_id);
}
 
function lendBook()
{
  var lendForm = {};
  jQuery("#lendForm :input").each(function(idx,ele){
    lendForm[jQuery(ele).attr('name')] = jQuery(ele).val();
  });
  
  jQuery.ajax({
    url:'index.php?option=com_lendr&controller=lend&format=raw&tmpl=component',
    type:'POST',
    data:lendForm,
    dataType:'JSON',
    success:function(data)
    {
      if ( data.success )
      {
        jQuery("#lendBookModal").modal('hide');
      }
    }
  });
}

您可能会注意到几个地方缺少错误消息。我们将在即将到来的清理文章中一次性编写所有这些。

步骤 3:添加愿望清单、等待清单和评论

我们将要处理的与书籍相关的有三个区域。愿望清单和等待清单功能相当简单。这两个都只是简单地加载一个模态框,并将特定书籍添加到用户的愿望清单或等待清单中。再次强调,这段代码在大多数方面与其他模态代码和借阅代码类似。由于评论代码比其他两个稍微复杂一些,我们将重点放在涉及评论过程的代码上。

注意:您可以在GitHub存储库中查看愿望清单和等待清单代码。

最初的想法是利用评论控制器来处理新的评论,但经过进一步思考,我决定从技术上讲,新的评论应该遵循与其他系统部分相同的“添加”控制器。这涉及对添加控制器进行一些重写,以便正确路由数据到正确的模型。

评论是从模态窗口创建的。模态框加载一个包含评论标题和摘要的表单。隐藏字段跟踪提交评论的书籍和用户。以下是新评论的表单。

joomla_root/components/com_lendr/views/review/tmpl/_add.php

<div id="newReviewModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="newReviewModal" aria-hidden="true">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
    <h3 id="myModalLabel"<>?php echo JText::_('COM_LENDR_ADD_REVIEW'); ?></h3>
  </div>
  <div class="modal-body">
  <div class="row-fluid">
    <form id="reviewForm">
      <input class="span12" type="text" name="title" placeholder="<?php echo JText::_('COM_LENDR_TITLE'); ?>" />
      <textarea class="span12" placeholder="<?php echo JText::_('COM_LENDR_SUMMARY'); ?>" name="review" rows="10"</textarea>
      <input type="hidden" name="user_id" value=">?php echo $this->user->id; ?>" />
      <input type="hidden" name="view" value="review" />
      <input type="hidden" name="book_id" value="<?php echo $this->book->book_id; ?>" />
      <input type="hidden" name="model" value="review" />
      <input type="hidden" name="item" value="review" />
      <input type="hidden" name="table" value="review" />
    </form>
  </div>
  </div>
  <div class="modal-footer">
    <button class="btn" data-dismiss="modal" aria-hidden="true"><?php echo JText::_('COM_LENDR_CLOSE'); ?<>/button>
    <button class="btn btn-primary" onclick="addReview()"><?php echo JText::_('COM_LENDR_ADD'); ?></button>
  </div>
</div>
注意:我们正在传递表和其他必要的字段,以便路由到适当的模型和功能。

以下是与评论过程相关的JavaScript。

joomla_root/components/com_lendr/assets/js/lendr.js

//add a review
function addReview()
{
  var reviewInfo = {};
  jQuery("#reviewForm :input").each(function(idx,ele){
    reviewInfo[jQuery(ele).attr('name')] = jQuery(ele).val();
  });
 
  jQuery.ajax({
    url:'index.php?option=com_lendr&controller=add&format=raw&tmpl=component',
    type:'POST',
    data:reviewInfo,
    dataType:'JSON',
    success:function(data)
    {
      if ( data.success ){
        console.log(data.html);
        jQuery("#review-list").append(data.html);
        jQuery("#newReviewModal").modal('hide');
      }else{
 
      }
    }
  });
}

在这个函数中,我们执行了几个操作。首先,我们使用一个巧妙的jQuery循环来获取所有表单数据并将其传递到控制器。然后提交表单并等待响应。如果响应成功,则将响应追加到评论列表中并隐藏模态窗口。这意味着我正在从AJAX调用中传递完整的HTML行。以下是更新后的控制器中如何处理这种情况。

joomla_root/components/com_lendr/controllers/add.php

<?php defined( '_JEXEC' ) or die( 'Restricted access' ); 
class LendrControllersAdd extends JControllerBase
{
  public function execute()
  {
    $app      = JFactory::getApplication();
    $return   = array("success"=>false);
 
    $modelName  = $app->input->get('model', 'Book');
    $view       = $app->input->get('view', 'Book');
    $layout     = $app->input->get('layout', '_entry');
    $item       = $app->input->get('item', 'book');
 
    $modelName  = 'LendrModels'.ucwords($modelName);
 
    $model = new $modelName();
    if ( $row = $model->store() )
    {
      $return['success'] = true;
      $return['msg'] = JText::_('COM_LENDR_SAVE_SUCCESS');
      $return['html'] = LendrHelpersView::getHtml($view, $layout, $item, $row);
    }else{
      $return['msg'] = JText::_('COM_LENDR_SAVE_FAILURE');
    }
    echo json_encode($return);
  }
}

返回给JavaScript的HTML是从助手文件中加载的。您会注意到我们传递了视图、布局、项和行到getHtml函数。在这种情况下,有必要审查助手文件中的getHtml函数。

joomla_root/components/com_lendr/helpers/view.php

function getHtml($view, $layout, $item, $data)
{
  $objectView = LendrHelpersView::load($view, $layout, 'phtml');
  $objectView->$item = $data;
  
  ob_start();
   echo $objectView->render();
   $html = ob_get_contents();
  ob_clean();
    
  return $html;
}

这个视图具有双重用途。首先,它加载一个位于View Helper文件早些时候的部分视图,然后一旦加载,它将该视图渲染到变量中。然后,这个变量被返回以传递给JavaScript,JavaScript将把它追加到页面上。

这就完成了评论过程。直接在Github存储库中查看所有相关文件。

步骤 4:搜索书籍

搜索过程是一个值得评估的有趣过程。我们可以采取一些方案。你可以将一个完整的搜索系统集成到你的组件中,或者利用Joomla中Finder组件、模块和插件中已经构建的系统。尽管在所有情况下使用Finder系统可能不合适,但在Lendr组件中,我们将利用这个机会与Finder集成。通过集成Finder,我们首先将简化必须添加到Lendr中的代码和结构,其次,我们还将能够展示使用Finder创建新内容类型插件所需的代码。

我为Finder编写的插件很简单,当然不能展示插件系统的所有典型功能。下面是我们正在编写的Finder插件相关的XML文件(我称之为“智能搜索 - 图书”)。

books.xml
books.php

这些函数被Finder用来索引正确的表,加载数据并在搜索结果中正确路由。由于本教程的级别,我将不会对每个这些函数进行过多详细介绍,也不会加载通常用于使组件语言特定和其他额外功能的二级路由辅助程序。如果你对搜索插件系统感兴趣,请在评论中留言或联系我获取更多信息。

第5步:总结

在这篇文章中,我们介绍了很多函数、结构设计和可以应用于任何其他组件的额外想法。我们探讨了如何最好地利用Bootstrap进行模态对话框,我们更深入地研究了javascript功能及其使用,然后我们将使用范围扩展到组件集成到二级插件。我故意没有包括每个编写的文件或每个修改的函数,只是为了保持本文的重点在组件开发的思想和概念上,而不是可以从以前的教程中更容易识别的个别函数。如果你对编写的任何代码有任何疑问,请不要犹豫,提出问题。

在下一篇文章中,我们将开始总结并完善代码。我们将涵盖管理员界面、在AJAX调用完成后在页面上正确使用实时更新,以及开始清理代码、删除不必要的文件,并探讨我们如何简化或减少代码的方法。

下载

从GitHub存储库中下载到目前为止存在的组件。

下载

访问完整的教程网站:http://lendr.websparkinc.com/

在下一篇教程中,我们将开始总结,添加管理员界面并清理代码。

在Joomla社区杂志上发表的一些文章代表了作者对特定主题的个人意见或经验,可能不与Joomla项目官方立场一致

0
Joomla! 3.1将于4月15日发布
Joomla! 是人们
 

评论

已经注册了吗? 在此登录
还没有评论。成为第一个发表评论的人

通过接受,您将访问由 https://magazine.joomla.net.cn/ 之外的第三方提供的服务