使用 Zend (1.12.17) 和 Ajax 的动态下拉列表

Posted

技术标签:

【中文标题】使用 Zend (1.12.17) 和 Ajax 的动态下拉列表【英文标题】:Dynamic Dropdoown List using Zend (1.12.17) and Ajax 【发布时间】:2016-04-24 09:46:43 【问题描述】:

我是 Zend 的新手,很难掌握如何使用 Ajax 动态填充下拉菜单。我创建了一个不使用 Zend 框架的工作版本,但现在将我的代码放入 Zend 证明比我最初想象的要困难得多。当我尝试运行我的应用程序时,Chrome 的开发者工具会输出到控制台:

GET http://example.com/crm/getcities.php?name=CDS%20Midwinter%20Meeting 404 (Not Found)tradeshowOptions @ tradeshows:423onchange @ tradeshows:484 

在我的应用程序控制器文件夹中,我有一个名为 CrmController.php 的控制器,如下所示:

<?php
class CrmController extends Zend_Controller_Action 

public function init()         
    if(!Zend_Auth::getInstance()->getIdentity() || !in_array('crm', unserialize(Zend_Auth::getInstance()->getIdentity()->permission)))
        $this->_helper->redirector('index', 'fm');
     
    $this->view->headLink()->appendStylesheet('/public/css/crm.css');
    $this->_auth = Zend_Auth::getInstance()->getIdentity();

    $this->_users = new Application_Model_User;       
    $this->_crms = new Application_Model_Crm;  
    $this->_products = new Application_Model_Product;

    $this->_helper->ajaxContext->addActionContext('crm', 'html')
                                   ->initContext();


public function tradeshowsAction()
    

我有一个名为 tradeshows.phtml 的视图,它看起来像:

<?php require_once('config.php'); ?>
<div class="row">
    <div class="col-lg-12">                   
        <h2 class="page-header">Sales CRM</h2>
        <ol class="breadcrumb">               
            <li><a href="/crm/prospect">Leads</a></li> 
            <li><a href="/crm/prospect">Prospects</a></li>             
            <li><a href="/crm/accounts">Accounts</a></li> 
            <li><a href="/crm/activity">Activities</a></li>
            <li class="active">Tradeshows</li>
        </ol>
    </div>    
</div>

<h3>Tradeshows</h3>



<script>
var name = "";
var city = "";
var year = "";

// Gets the list of cities to populate the second drop down.
function tradeshowOptions(tsname) 
        name = tsname;
    if (tsname == "") 
        document.getElementById("txtHint").innerHTML = "";
        return;
     else  
        if (window.XMLHttpRequest) 
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
         else 
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        
        xmlhttp.onreadystatechange = function() 
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) 
                document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
            
        ;

        xmlhttp.open("GET","getcities.php?name="+name,true);
        xmlhttp.send();

                name = tsname;
                console.log(name);
    


// Get the list of cities to populate the third drop down.
function yearOptions(tscity) 
        city = tscity;
    if (tscity == "") 
        document.getElementById("txtHint2").innerHTML = "";
        return;
     else  
        if (window.XMLHttpRequest) 
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
         else 
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        
        xmlhttp.onreadystatechange = function() 
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) 
                document.getElementById("txtHint2").innerHTML = xmlhttp.responseText;
            
        ;
        xmlhttp.open("GET","get_year.php?name="+name+"&city="+city,true);
        xmlhttp.send();
                city = tscity;
                console.log(name + " " + city);
    


// Get the data list.
function dataSet(tsyear) 
        year = tsyear;
    if (tsyear == "") 
        document.getElementById("txtHint3").innerHTML = "";
        return;
     else  
        if (window.XMLHttpRequest) 
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
         else 
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        
        xmlhttp.onreadystatechange = function() 
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) 
                document.getElementById("txtHint3").innerHTML = xmlhttp.responseText;
            
        ;
        xmlhttp.open("GET","get_data.php?name="+name+"&city="+city+"&year="+year,true);
        xmlhttp.send();
                console.log(name + " " + city + " " + year);
    

</script>

<form>  
    Select Tradeshow:
    <select name="shows" onchange="tradeshowOptions(this.value)">
          <option value="">Select a Tradeshow:</option>
            <?php
              $sql = 'SELECT * FROM tradeshows GROUP BY name ORDER BY name asc;';
              $i = 0;
                foreach ($conn->query($sql) as $row) 
                    echo "<option value='$row[name]'>$row[name]</option>";                  
                    $i++;
              
            ?>
    </select>
</form>

<br>
<div id="txtHint">&nbsp;</div>
<div id="txtHint2">&nbsp;</div>
<div id="txtHint3">&nbsp;</div>

<link href='/public/css/crm.css' rel='stylesheet' />

最后但同样重要的是,我有我的 getcities.php 文件,我不知道该放在哪里。我也尝试将其命名为 getcities.ajax.phtml 并将其放入视图中,但似乎没有任何效果。

<!DOCTYPE html>
<html>
<head></head>
<body>
<form>  
    Select City:
    <select name="cities" onchange="yearOptions(this.value)">
            <option>Please select a city...</option>
            <?php
                // Database Connection
                require('config.php');

                // Global Variables from _GET
                $name = strval($_GET['name']);

                // mysql Query
              $sql = "SELECT * FROM tradeshows WHERE name LIKE '$name' GROUP BY city ORDER BY city asc;";

                // Output Each MySQL Result in Dropdown Menu
              $i = 0;
                foreach ($conn->query($sql) as $row) 
                    echo "<option value='$row[city]'>$row[city]</option>";
                    $i++;
              
            ?>
    </select>
</form>
</body>
</html>

请随意撕开我的代码。我真的很想学习。另外,我意识到我的代码不是那么干燥,如果有人可以提供一些建议,我将不胜感激。

谢谢!

【问题讨论】:

【参考方案1】:

您可以考虑查看 MVC 模式指南,Zend 框架围绕该模式构建:https://softwareengineering.stackexchange.com/questions/127624/what-is-mvc-really。

我建议您了解 MVC,否则您将与框架作斗争,将代码塞进它不想出现的地方。例如,getcities.php 是应分离为模型类、视图脚本和控制器操作的事物的组合。你不知道把这个文件放在哪里,因为它确实不属于你的应用程序。

这是我将采取的方法...首先,让我们创建一个示例控制器,用于响应对城市列表的 AJAX 请求:

<?php
class NewController extends Zend_Controller_Action


    public function init()
    
        $contextSwitch = $this->_helper->getHelper('contextSwitch');

        // The helper will detect a request for JSON and setup the getcities
        // action to return JSON automatically.  No view script required.
        $contextSwitch->addActionContext('getcities', 'json')->initContext();
    

    public function getcitiesAction()
    
        // Instantiate cities model.
        $cities_model = new Application_Model_Cities();

        // Get list of cities by simply getting all records.
        $cities_list = $cities_model->getCities();

        // JSON helper will emit all view variables in JSON format.
        $this->view->cities_list = $cities_list;

    

接下来,创建一个模型来表示并返回您的城市列表:

/**
 * Model class to represent cities and interact with database.
 *
 */
class Application_Model_Cities extends Zend_Db_Table_Abstract

    // Tell the class what table to use.
    protected $_name = 'tradeshows';

    public function getCities($name = false)
    
        if($name === false)
          // If no name supplied, match all.
          $name = '%';
        
        $sql = 'SELECT * FROM tradeshows WHERE name LIKE ? GROUP BY city ORDER BY city asc';
        return $this->getAdapter()->fetchAll($sql,$name);
    

将模型类放在应用程序的“模型”目录中。看起来您当前正在 config.php 中手动连接到您的数据库。您应该考虑使用 Zend DB 引导您的数据库连接。我的示例模型依赖于默认数据库连接:Registering Zend Database Adapter in Registry

您可以通过这样的 URL 调用上述代码:http://example.com/crm/getcities/format/json,您应该会看到以 JSON 格式显示的城市列表。

我认为这足以让您指出正确的方向。不要在生产环境中使用此代码,我已经采取了一些捷径来简化此示例的目的。

【讨论】:

以上是关于使用 Zend (1.12.17) 和 Ajax 的动态下拉列表的主要内容,如果未能解决你的问题,请参考以下文章

PHP Zend Framework:禁用布局和视图 - 用于AJAX

Zend框架:禁用布局和视图-对于AJAX

如何在 zend 框架 2 或 AjaxContext 中使用 ajax?

ZF2 - 使用 Ajax 填充选择

Zend 框架中的 Ajax 搜索需要帮助

Zend 框架自动完成