Zend FrameWork 2在表单中获取ServiceLocator并填充下拉列表

Jul*_*ins 16 zend-framework2

我需要从表单中获取适配器,但仍然不能.

在我的控制器中,我可以使用以下方法恢复适配器:

// module/Users/src/Users/Controller/UsersController.php
public function getUsersTable ()
{
    if (! $this->usersTable) {
        $sm = $this->getServiceLocator();
        $this->usersTable = $sm->get('Users\Model\UsersTable');
    }
    return $this->usersTable;
}
Run Code Online (Sandbox Code Playgroud)

在我的模块中,我这样做了:

// module/Users/Module.php  
public function getServiceConfig()
{
    return array(
            'factories' => array(
                    'Users\Model\UsersTable' =>  function($sm) {
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $uTable     = new UsersTable($dbAdapter);
                        return $uTable;
                    },
                    //I need to get this to the list of groups
                    'Users\Model\GroupsTable' =>  function($sm) {
                        $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                        $gTable     = new GroupsTable($dbAdapter);
                        return $gTable;
                    },
            ),
    );
}
Run Code Online (Sandbox Code Playgroud)

有人能举例说明如何从组表单中获取适配器吗?

我已经将此示例关注到我的表单用户:http: //framework.zend.com/manual/2.0/en/modules/zend.form.collections.html

从这里编辑...

也许我表示自己错了提问.

我真正需要做的是使用来自我的表组的信息填充选择(下拉).

所以我需要通过ServiceLocatorAwareInterface(参见此链接)实现我的userForm类中的服务,因为默认情况下,Zend Framework MVC注册一个初始化器,它将注入ServiceManager实例ServiceLocatorAwareInterface实现任何类.

从表组中检索值并填充选择后.

问题在于我尝试过的所有方法,getServiceLocator()都会返回:

Call to a member function get() on a non-object in
D:\WEBSERVER\htdocs\Zend2Control\module\Users\src\Users\Form\UsersForm.php
on line 46
Run Code Online (Sandbox Code Playgroud)

我只想在我的UserForm中执行此操作...

namespace Users\Form;

use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Form\Element;
use Zend\Form\Form;

class UsersForm extends Form implements ServiceLocatorAwareInterface
{

    protected $serviceLocator;

    public function getServiceLocator ()
    {
        return $this->serviceLocator;
    }

    public function setServiceLocator (ServiceLocatorInterface $serviceLocator)
    {
        $this->serviceLocator = $serviceLocator;
    }

    public function __construct ($name = null)
    {
        parent::__construct('users');

        $this->setAttribute('method', 'post');        

        $sm = $this->getServiceLocator();

        $groups = $sm->get('Users\Model\GroupsTable')->fetchAll(); // line 46       

        $select = new Element\Select('groups');

        $options = array();

        foreach ($groups as $group) {

            $options[$group->id] = $group->name;
        }

        $select->setValueOptions($options);

        $this->add($select);

        // and more elements here...
Run Code Online (Sandbox Code Playgroud)

tim*_*dev 7

这里的其他各种答案通常是正确的,因为ZF <2.1.

一旦2.1出来,该框架有一个非常好的解决方案.这或多或少正式化了DrBeza的解决方案,即:使用初始化程序,然后将任何表单引导移动到初始化所有依赖项后调用的init()方法.

我一直在玩开发分支,它运作得很好.


And*_*rew 6

这是我用来解决这个问题的方法.

首先,您要使表单实现ServiceLocatorInterface.

然后,您仍然需要手动注入服务定位器,并且因为整个表单是在contrstuctor中生成的,您还需要通过构造函数注入(尽管在构造函数中没有理想的构建它)

Module.php

/**
 * Get the service Config
 * 
 * @return array 
 */
public function getServiceConfig()
{
    return array(
        'factories' => array(
            /**
             * Inject ServiceLocator into our Form
             */
            'MyModule\Form\MyForm' =>  function($sm) {
                $form = new \MyModule\Form\MyFormForm('formname', $sm);
                //$form->setServiceLocator($sm);

                // Alternativly you can inject the adapter/gateway directly
                // just add a setter on your form object...
                //$form->setAdapter($sm->get('Users\Model\GroupsTable')); 

                return $form;
            },
        ),
    );
}
Run Code Online (Sandbox Code Playgroud)

现在在您的控制器中,您可以获得如下表单:

// Service locator now injected
$form = $this->getServiceLocator()->get('MyModule\Form\MyForm');
Run Code Online (Sandbox Code Playgroud)

现在,您将可以访问表单中的完整服务定位器,以获取任何其他服务,例如:

$groups = $this->getServiceLocator()->get('Users\Model\GroupsTable')->fetchAll();
Run Code Online (Sandbox Code Playgroud)


mic*_*lbn 1

在 module.php 中我创建了两个服务。看看我如何将适配器提供给表单。

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'db_adapter' =>  function($sm) {
                $config = $sm->get('Configuration');
                $dbAdapter = new \Zend\Db\Adapter\Adapter($config['db']);
                return $dbAdapter;
            },

            'my_amazing_form' => function ($sm) {
                return new \dir\Form\SomeForm($sm->get('db_adapter'));
            },

        ),
    );
}
Run Code Online (Sandbox Code Playgroud)

在表单代码中,我将该提要用于任何内容:

namespace ....\Form;

use Zend\Form\Factory as FormFactory;
use Zend\Form\Form;

class SomeForm extends Form
{

    public function __construct($adapter, $name = null)
    {
        parent::__construct($name);
        $factory = new FormFactory();

        if (null === $name) {
            $this->setName('whatever');
        }

    }
}
Run Code Online (Sandbox Code Playgroud)