Zend框架2获取服务定位在形式和填充下拉列表(Zend FrameWork 2 Get Servi

2019-07-31 15:43发布

我需要从表单适配器,但还是没能。

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

// 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;
}

在我的模块我这样做:

// 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;
                    },
            ),
    );
}

可能有人给我一个例子,如何获得从小组形式的适配器表?

我按照这个例子,我的表单的用户: http://framework.zend.com/manual/2.0/en/modules/zend.form.collections.html

从在此编辑的...

也许是我表达自己错了要问的问题。

我真正需要做的是从我的表组填充选择(下拉)的信息。

所以,我需要用我的ServiceLocatorAwareInterface类用户窗体里面的服务( 见这个链接 )来实现,因为默认情况下,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

我只是想做到这一点在我的窗体...

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...

Answer 1:

其他各种答案在这里通常是正确的,对于ZF <2.1。

一旦2.1是出,该框架有一个相当不错的解决方案 。 这更多或更少的形式化DrBeza溶液,即:使用的初始化,然后将所有的依赖已被初始化后调用任何形状自举到init()方法。

我一直在玩与发展分支,它那很好。



Answer 2:

这是我用来绕过这个问题的方法。

首先,你想使你的形式实现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;
            },
        ),
    );
}

现在你的控制器中您得到您的形式是这样的:

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

现在你将有表单内访问完整的服务定位,得到的任何其他服务等,如持有:

$groups = $this->getServiceLocator()->get('Users\Model\GroupsTable')->fetchAll();


Answer 3:

在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'));
            },

        ),
    );
}

在窗体的代码我用饲料什么:

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');
        }

    }
}


Answer 4:

我们处理这个模型中,通过添加接受形式的方法

public function buildFormSelectOptions($form, $context = null)
{
    /** 
     * Do this this for each form element that needs options added
     */
    $model = $this->getServiceManager()->get('modelProject');

    if (empty($context)){
        $optionRecords = $model->findAll();
    } else {
        /**
         * other logic for $optionRecords
         */
    }

    $options = array('value'=>'', 'label'=>'Choose a Project');
    foreach ($optionRecords as $option) {
        $options[] = array('value'=>$option->getId(), 'label'=>$option->getName());
    }

    $form->get('project')->setAttribute('options', $options);
}

由于形式按引用传递,我们可以做这样的事情在形式内置控制器:

    $builder = new AnnotationBuilder();
    $form = $builder->createForm($myEntity);
    $myModel->buildFormSelectOptions($form, $myEntity);

    $form->add(array(
        'name' => 'submitbutton',
        'attributes' => array(
            'type'  => 'submit',
            'value' => 'Submit',
            'id' => 'submitbutton',
        ),
    ));

    $form->add(array(
        'name' => 'cancel',
        'attributes' => array(
            'type'  => 'submit',
            'value' => 'Cancel',
            'id' => 'cancel',
        ),
    ));

注:该示例假设基本形式是通过注解建立,但不要紧,你如何创建初始的形式。



Answer 5:

其他答案的另一种方法是创建一个的ServiceManager初始化程序。

现有的初始化程序的一个例子是怎样,如果你的实例实现ServiceLocatorAwareInterface的的ServiceManager注入。

这个想法是创建一个你检查你的初始化器的接口,这个接口可以是这样的:

interface FormServiceAwareInterface
{
    public function init();
    public function setServiceManager(ServiceManager $serviceManager);
}

你的初始化器可以是什么样子的一个例子:

class FormInitializer implements InitializerInterface
{
    public function initialize($instance, ServiceLocatorInterface $serviceLocator)
    {
        if (!$instance instanceof FormServiceAwareInterface)
        {
            return;
        }

        $instance->setServiceManager($serviceLocator);
        $instance->init();
    }
}

凡是发生在init()将有机会获得ServiceManager 。 当然,你需要你的初始化添加到您的SM配置。

它不是完美的,但它工作正常,满足我的需求,也可以应用于任何字段集从拉的ServiceManager。



Answer 6:

这是我用身边这个问题得到的方式。

首先,在Module.php,创建服务(就像你这样做):

// 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;
                    },
            ),
    );
}

然后在控制器中,我到了服务的引用:

$users = $this->getServiceLocator()->get('Test\Model\TestGroupTable')->fetchAll();
        $options = array();
        foreach ($users as $user)
           $options[$user->id] = $user->name;
        //get the form element
        $form->get('user_id')->setValueOptions($options);

和中提琴,这项工作。



文章来源: Zend FrameWork 2 Get ServiceLocator In Form and populate a drop down list