处理Zend Framework中的依赖关系2表格
我想在ZF2中构建一个表单。当我想从数据库表中填充选择输入元素的选项数组时,问题就出现了。 @timdev对这个问题的回应Zend FrameWork 2 Get ServiceLocator In Form and populate a drop down list指出了ZF2文档描述'正确'方法的地方。我仔细地跟踪了这一点,但我怀疑他们必须留下明显的代码,假设我能填补空白,因为我无法实现它。任何人都可以看到我做错了什么?处理Zend Framework中的依赖关系2表格
我开始用一种形式,而我添加一个字段:
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表中拉出数组数据。
现在我成立了我的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);
}
)
);
}
这段代码是直接从文档。我已经尝试添加
return $fieldset;
到PropertyFieldset工厂,我甚至尝试添加
'invokables' => array(
'PropertyFieldset' => 'Ctmm\Form\PropertyFieldset'
)
到getFormElementConfig阵列,以及与可调用替换工厂。
最后一步是使用表单元素管理器来创建我的控制器操作形式:
public function addAction() {
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Ctmm\Form\AddPropertyForm');
}
无论我做什么,我得到一个错误称的ServiceManager无法创建PropertyFieldset:
的Zend \的ServiceManager \异常\ 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)
33号线在AddPropertyForm.php是我尝试添加自己的自定义PropertyFieldset。很明显,我在字段集本身或我声明的方式中有一个错误。我尝试过不注入PropertyType依赖项,但这没有什么区别。为了完整起见,我的属性类型模型的代码是:
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;
}
}
编辑:
我没有一个答案,但我做了一些更多的研究。我直接在控制器中创建了一个fieldset来测试我的PropertyFieldset类和它的依赖模型。
$property_type = $this->getServiceLocator()->get('Ctmm\Model\PropertyType');
$fieldset = new PropertyFieldset($property_type);
这没有立即起作用。首先,我不得不采取暗示出字段集构造器
public function __construct(PropertyFieldset $property_type) {
成了
public function __construct($property_type) {
然后我不得不添加
parent::__construct('propertyfieldset');
之前,将允许我补充的元素。
有一次,我添加了这些变化,我能够在控制器中创建一个PropertyFieldset对象。我可以通过var_dump()来测试它。
不幸的是,这些更改PropertyFieldset类没有解决根本问题,所以,当我尝试创建控制器的形式,它会产生相同的错误了。我有,至少免除了PropertyFieldset类和它的依赖模型,它告诉我,我的Module.php类中的getFormElementConfig()有错误
所以我得到了这个工作与一些小的改变:
正如你提到的PropertyFieldSet
应该叫父母建造像这样:
parent::__construct('propertyfieldset');
ElementConfig应该像这样:
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应该像这样:
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',
));
}
}
而不是使用__construct我们使用的init()。这个函数显然是在工厂实例化时调用的:http://framework.zend.com/apidoc/2.1/classes/Zend.Form.Form.html#init
关于构建select,我将TableGateway对象传递给fieldSet而不是模型。然后用使用fetchall功能,我们可以做的形式如下:
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
),
));
}
}
希望这有助于:)
感谢您的帮助艾登,我真的很感激。如果我能为额外的TableGateway建议额外提供+1,我会。 – 2013-03-16 18:47:09
我想这个代码,工厂工作,如果我做了他们的var_dump他们看起来确定。但我无法让它显示在窗体上。它只给我空白的文本字段。任何线索都可能是错误的? – Rickard 2013-06-29 20:06:57
什么是您的AddPropertyForm工厂是什么样子?至于类型暗示。我认为你需要使用完整的命名空间,所以:使用Ctmm \ Model \ PropertyType;或将完整路径放在构造函数中 – 2013-03-16 16:26:19
我不使用工厂来创建AddPropertyForm。该窗体使用新的FormElementManager在控制器中创建。该文档坚持使用它来创建表单,以便它获取getFormElementConfig()中定义的元素。 – 2013-03-16 16:33:27
只是有一个混乱与它,我认为如果你改变__construct方法init在AddPropertyForm它应该工作。您还需要从工厂返回现场组。我会仔细检查一下并发布答案。 – 2013-03-16 17:39:31