处理 Zend Framework 2 表单中的依赖项 [英] Handling dependencies in Zend Framework 2 Forms
问题描述
我正在尝试在 ZF2 中构建一个表单.当我想从数据库表中填充 Select 输入元素的选项数组时,问题就出现了.对此问题的回应 ZendFrameWork 2 Get ServiceLocator In Form and populate a drop down list by @timdev 将我指向了描述正确"方法的 ZF2 文档.我仔细地遵循了这一点,但我怀疑他们一定遗漏了明显的代码,假设我可以填补空白,因为我无法让它工作.谁能看到我做错了什么?
I am trying to build a form in ZF2. The problem comes when I want to populate the options array of a Select input element from a database table. A response to this question Zend FrameWork 2 Get ServiceLocator In Form and populate a drop down list by @timdev pointed me to the ZF2 docs where the 'correct' method is described. I followed this carefully but I suspect that they must have left obvious code out assuming I could fill in the gaps as I cannot get it to work. Can anyone see what I am doing wrong?
我从添加字段集的表单开始:
I start with a form to which I add a fieldset:
namespace Ctmm\Form;
use Zend\Form\Form;
class AddPropertyForm extends Form {
public function __construct() {
parent::__construct('AddProperty');
$this->setName('addProperty');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'property',
'type' => 'PropertyFieldset'
));
}}
然后我创建字段集:
namespace Ctmm\Form;
use Ctmm\Model;
use Zend\Form\Fieldset;
class PropertyFieldset extends Fieldset {
public function __construct(PropertyType $property_type) {
$this->add(array(
'name' => 'property_type',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'required' => true,
),
'options' => array(
'label' => 'Property Type',
'value_options' => array(
0 => 'Detached house',
1 => 'Semi-detached house',
2 => 'Terraced house',
3 => 'Bungalow',
4 => 'Maisonette',
5 => 'Flat',
6 => 'Land',
7 => 'Development Opportunity',
),
),
));
}
}
如您所见,我将 PropertyType 依赖项注入到字段集中.在这个阶段,我什至还没有使用它来生成选项数组.我对数组值进行了硬编码,以避免添加另一个可能的错误来源.获得要呈现的表单后,我将尝试从 PropertyType 表中提取数组数据.
As you can see I inject PropertyType dependency into the fieldset. At this stage, I have not even used this to generate the options array. I have hard coded the array values to avoid adding another source of possible errors. Once I get the form to render I will then try to pull the array data from the PropertyType table.
现在我在 Module.php 中设置表单元素管理器:
Now I set up the form element manager in my Module.php:
namespace Ctmm;
use Ctmm\Form\PropertyFieldset;
use Zend\ModuleManager\Feature\FormElementProviderInterface;
class Module implements FormElementProviderInterface {
public function getFormElementConfig() {
return array(
'factories' => array(
'PropertyFieldset' => function($sm) {
$serviceLocator = $sm->getServiceLocator();
$property_type = $serviceLocator->get('Ctmm\Model\PropertyType');
$fieldset = new PropertyFieldset($property_type);
}
)
);
}
}
此代码直接来自文档.我试过添加
This code is straight from the docs. I have tried adding
return $fieldset;
到 PropertyFieldset 工厂,我什至尝试添加
to the PropertyFieldset factory, and I have even tried adding
'invokables' => array(
'PropertyFieldset' => 'Ctmm\Form\PropertyFieldset'
)
到 getFormElementConfig 数组,以及用可调用对象替换工厂.
to the getFormElementConfig array, as well as replacing the factory with the invokable.
最后一步是使用表单元素管理器在我的控制器操作中创建表单:
The last step is to create the form in my controller action using the form element manager:
public function addAction() {
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Ctmm\Form\AddPropertyForm');
}
无论我做什么,我都会收到一条错误消息,指出 Servicemanager 无法创建 PropertyFieldset:
Whatever I do, I get an error saying the Servicemanager cannot create the PropertyFieldset:
Zend\ServiceManager\Exception\ServiceNotFoundException
Zend\ServiceManager\Exception\ServiceNotFoundException
文件:
/home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:456
留言:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for PropertyFieldset
堆栈跟踪:
#0 /home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php(103): Zend\ServiceManager\ServiceManager->get('PropertyFieldse...', true)
#1 /home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/Form/Factory.php(110): Zend\ServiceManager\AbstractPluginManager->get('PropertyFieldse...')
#2 /home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/Form/Form.php(145): Zend\Form\Factory->create(Array)
#3 /home/mike/public_html/ctmm/module/Ctmm/src/Ctmm/Form/AddPropertyForm.php(33): Zend\Form\Form->add(Array)
AddPropertyForm.php 中的第 33 行是我尝试添加自定义 PropertyFieldset 的地方.显然,我在字段集本身或声明它的方式中存在错误.我试过不注入 PropertyType 依赖项,但这没有区别.为了完整起见,我的 PropertyType 模型的代码是:
Line 33 in AddPropertyForm.php is where I try to add my custom PropertyFieldset. Clearly I have an error in the fieldset itself or in the way I am declaring it. I have tried without injecting the PropertyType dependency, but that makes no difference. For completeness, the code for my PropertyType model is:
namespace Ctmm\Model;
class PropertyType {
public $id;
public $property_type;
protected $adapter;
public function __construct($adapter) {
$this->adapter = $adapter;
}
public function exchangeArray($data) {
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->property_type = (isset($data['property_type'])) ? $data['property_type'] : null;
}
public function getPropertyType() {
return $this->property_type;
}
public function fetchAll() {
$sql_query = "SELECT id, property_type from property_type";
$statement = $this->adapter->createStatement($sql_query);
$results = $statement->execute();
return $results;
}
}
我没有答案,但我做了更多调查.我直接在控制器中创建了一个字段集来测试我的 PropertyFieldset 类及其依赖模型.
I don't have an answer but I have done some more investigation. I created a fieldset directly in the controller to test my PropertyFieldset class and it's dependent model.
$property_type = $this->getServiceLocator()->get('Ctmm\Model\PropertyType');
$fieldset = new PropertyFieldset($property_type);
这并没有立即起作用.首先,我必须从 Fieldset 构造函数中取出提示
This did not work immediately. First, I had to take the hinting out of the Fieldset contructor
public function __construct(PropertyFieldset $property_type) {
变成了
public function __construct($property_type) {
然后我不得不添加
parent::__construct('propertyfieldset');
在它允许我添加元素之前.
before it would allow me to add an element.
一旦我添加了这些更改,我就能够在控制器中创建一个 PropertyFieldset 对象.我可以通过 var_dump() 对其进行测试.
Once I had added these changes I was able to create a PropertyFieldset object in the controller. I could test this by var_dump()ing it.
不幸的是,对 PropertyFieldset 类的这些更改并没有解决基本问题,因此当我尝试在控制器中创建表单时,它会生成与以前相同的错误.我已经,至少免除了 PropertyFieldset 类和它的依赖模型,它告诉我我的 Module.php 类中的 getFormElementConfig() 有问题
Unfortunately, these changes to the PropertyFieldset class did not fix the basic problem, so that when I try to create the form in the controller, it generates the same error as before. I have, at least exonerated the PropertyFieldset class and it's dependent model, which says to me that I have something wrong in the getFormElementConfig() in my Module.php class
推荐答案
所以我做了一些小的改动:
So I got this to work with a few minor changes:
正如您所指出的,PropertyFieldSet
应该像这样调用父结构:
As you noted the PropertyFieldSet
should call the parents construct like so:
parent::__construct('propertyfieldset');
ElementConfig 应该是这样的:
ElementConfig should be like so:
public function getFormElementConfig() {
return array(
'factories' => array(
'PropertyFieldset' => function($sm) {
$serviceLocator = $sm->getServiceLocator();
$property_type = $serviceLocator->get('Ctmm\Model\PropertyType');
$fieldset = new PropertyFieldset($property_type);
return $fieldset;
},
)
);
}
AddPropertyForm 应该是这样的:
And the AddPropertyForm should be like so:
namespace Ctmm\Form;
use Zend\Form\Form;
class AddPropertyForm extends Form {
public function init() {
parent::__construct('AddProperty');
$this->setName('addProperty');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'addproperty',
'type' => 'PropertyFieldset',
));
}
}
我们使用 init() 代替 __construct.工厂实例化时显然会调用此函数:http://framework.zend.com/apidoc/2.1/classes/Zend.Form.Form.html#init
Instead of using __construct we use init(). This function is apparently called when instantiated by factory: http://framework.zend.com/apidoc/2.1/classes/Zend.Form.Form.html#init
关于构建选择,我会将 TableGateway 对象传递给 fieldSet 而不是模型.然后使用 fetchAll 函数,我们可以在表单中执行以下操作:
Regarding building the select, I would pass a TableGateway object to the fieldSet instead of a model. Then using a fetchAll function we could do the following in the form:
class PropertyFieldset extends Fieldset {
public function __construct(PropertyTypeTable $propertyTypeTable) {
parent::__construct('propertyfieldset');
$propertyValOpts = array();
foreach($propertyTypeTable->fetchAll() as $propertyRow) {
array_push($propertyValOpts,$propertyRow->property_type);
}
$this->add(array(
'name' => 'property_type',
'type' => 'Zend\Form\Element\Select',
'attributes' => array(
'required' => true,
),
'options' => array(
'label' => 'Property Type',
'value_options' => $propertyValOpts
),
));
}
}
希望这有帮助:)
这篇关于处理 Zend Framework 2 表单中的依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!