阅读时间 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仓库中找到其余的模态文件(结构类似)。

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

现在,我们已经加载并显示模态窗口以显示更多信息,我们想通过使用这些模态窗口来为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模型,该模型将处理lend函数调用。以下是位于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调用将表单数据传递到上述lend控制器。如果控制器/模型执行成功,则关闭模态窗口。

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/ 之外的第三方提供的服务