我需要从表单中获取适配器,但仍然不能。
在我的控制器中,我可以使用以下方法恢复适配器:
// 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(see this link)实现我的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
我只想在我的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...
答案 0 :(得分:7)
这里的其他各种答案通常是正确的,因为ZF< 2.1。
2.1出局后,框架有一个漂亮的nice solution。这或多或少正式化了DrBeza的解决方案,即:使用初始化程序,然后将任何表单引导移动到初始化所有依赖项后调用的init()方法。
我一直在玩开发分支,它运行得很好。
答案 1 :(得分: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;
},
),
);
}
现在在您的控制器中,您可以获得这样的表单:
// Service locator now injected
$form = $this->getServiceLocator()->get('MyModule\Form\MyForm');
现在您可以访问表单中的完整服务定位器,以获取其他任何服务,例如:
$groups = $this->getServiceLocator()->get('Users\Model\GroupsTable')->fetchAll();
答案 2 :(得分: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'));
},
),
);
}
在表单代码中,我将该Feed用于任何内容:
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');
}
}
}
答案 3 :(得分:0)
我们通过添加接受表单
的方法在模型中处理此问题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',
),
));
注意:该示例假定基本表单是通过注释构建的,但是如何创建初始表单并不重要。
答案 4 :(得分:0)
其他答案的另一种方法是创建一个ServiceManager初始化程序。
现有Initializer的一个示例是,如果您的实例实现ServiceLocatorAwareInterface,将如何注入ServiceManager。
想法是创建一个在Initialiser中检查的界面,这个界面可能如下所示:
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中提取的任何Fieldsets。
答案 5 :(得分:0)
这是我用来解决这个问题的方式。
首先,在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);
中提琴,那工作。