【问题标题】:ZF2 - Populate Select with AjaxZF2 - 使用 Ajax 填充选择
【发布时间】:2015-12-21 04:21:36
【问题描述】:

我在 ProductsForm.php 中有我的:

命名空间产品\表格; 使用 Zend\Form\Form; 使用 Zend\Db\Adapter\AdapterInterface; 使用 Zend\Db\TableGateway\TableGateway; 使用 Zend\Db\Sql\Select; 类 ProductsForm 扩展 Form { 公共函数 __construct(AdapterInterface $dbAdapter) { $this->适配器 = $dbAdapter; 父::__construct('products'); $this->add(数组( '名称' => '状态', '类型' => '选择', '属性' => 数组( 'class' => '表单控制', ), '选项' => 数组( 'empty_option' => '选择...', 'value_options' => $this->getStatesForSelect() ), )); $this->add(数组( '名称' => '城市', '类型' => '选择', '属性' => 数组( 'class' => '表单控制', ), '选项' => 数组( 'empty_option' => '选择...', 'value_options' => $this->getCitiesForSelect() ), )); } 公共函数 getStatesForSelect() { $dbAdapter = $this->适配器; $table = new TableGateway('states', $dbAdapter); $result = $table->select(function (Select $select) { $select->order('name DESC'); }); foreach ($result as $res) { $selectData[$res['id']] = $res['name']; } 返回$选择数据; } 公共函数 getCitiesForSelect($state_id) { ??? :( 从 state_id = $state_id 的城市中选择? } }

我只想在用户选择“状态”时执行 getCitiesForSelect()...然后根据 state.id 值用数据库中的值填充它

我该怎么做?

【问题讨论】:

    标签: ajax select zend-framework zend-framework2 zend-form


    【解决方案1】:

    首先,不要将getStatesForSelectgetCitiesForSelect 方法放在表单中。表单是控制器层的一部分,每个数据库请求都属于模型层: http://framework.zend.com/manual/current/en/modules/zend.mvc.intro.html

    第二:如果您这样做了,您可以创建一个操作,该操作将返回一个带有请求状态的 json,并通过 ajax 调用它。要正确加载所有内容并使其美观,您还必须对表单进行一些更改:

    $this->add(array(
        'name' => 'state',
        'type' => 'select',
        'attributes' => array(
            'class' => 'form-control',
            'id'    => 'select-state',
        ),
        'options' => array(
            'class' => 'state-option',
            'empty_option' => 'Select...',
        ),
    ));
    
    $this->add(array(
        'name' => 'city',
        'type' => 'select',
        'attributes' => array(
            'class' => 'form-control',
            'id'    => 'select-city',
            'style' => 'display:none',
        ),
        'options' => array(
            'empty_option' => 'Select...',
        ),
    ));
    

    我删除了从数据库中获取选项的方法,因为如上所述,这应该是模型表的工作。正如 NandaKumar 已经写的那样,您在控制器中设置了这些选项:

    $states = $modelTable->getStatesForSelect();
    $form->get('state')->setValueOptions($states);
    

    但这只会填满州,我们也需要一些东西来填满城市!为此,我们将定义一个 ajax 操作来获取这些操作:

    public function stateCitiesAction()
    {
        if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) 
             && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
            $stateId = $this->params()->fromRoute("id");
            // get your cities table
            // getCitiesForSelect() needs to return an array!
            $cities = $citiesTable->getCitiesForSelect();
            return new JsonModel($cities);
        } else {
            // return a 404 if this action is not called via ajax
           $this->getResponse()->setStatusCode(404);
            return NULL;
        }
    }
    

    if 语句是为了确保这个动作只能通过 ajax 访问。如果不是,它将返回 404。

    我只是在此示例中假设模型操作将返回与表单中的方法相同的数组。尽管您可能会争论哪个级别应该转换数据库结果,模型本身或控制器。但为了保持示例简单,我这样做了。

    要正确解析 JsonModel,您需要在 module.config.php 中包含 ViewJsonStrategy。否则你会得到一个错误,因为 Zend 会试图找到一个视图脚本。

    'view_manager'    => array(
        //...
        'strategies' => array(
            'ViewJsonStrategy',
        ),
    ),
    

    另外,我们还需要传递 id。路由参数是最常用的方法,我们需要将其包含在路由定义中。此代码不是最终解决方案,仅应向您展示如何在配置中执行此操作:

    'poducts' => array(
        'type'    => 'Segment',
        'options' => array(
            'route'       => '/products/[:controller][/:action][/:id]',
            'constraints' => array(
                'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
                'action'     => '[a-zA-Z][a-zA-Z0-9_-]*',
                'id'         => '[0-9]*',
            ),
            'defaults'    => array(
                '__NAMESPACE__' => 'Application\Controller',
                'controller'    => 'Index',
                'action'        => 'index',
            ),
        ),
    ),
    

    有关路由的更多信息,请参阅: http://framework.zend.com/manual/current/en/modules/zend.mvc.routing.html

    唷,我们快完成了!唯一剩下的是填充城市选项的 ajax 调用。我是通过 jQuery 做到的:

    $(document).ready(function () {
    
        $("#select-state").change(function () {
            var stateId = $(this).val();
            if(stateId !== "") {
                // you might want to change this
                var url = "products/index/state-cities/"+stateId;
                $.getJSON( url, function( data ) {
                    var options = "";
                    $.each(data, function(id, city) {
                        options += "<option value='" + id + "'>" + city + "</option>";
                    });
                    $("#select-city").html(options).fadeIn();
                });
            }
        });
    
    });
    

    并不是我不知道你的路由,你可能需要更改 url。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2023-03-19
      • 2014-05-24
      • 2012-04-17
      • 1970-01-01
      相关资源
      最近更新 更多