Mik*_*lly 4 zend-form zend-framework2
我正在尝试在ZF2中构建一个表单.当我想从数据库表中填充Select输入元素的options数组时,问题出现了.对此问题的回答Zend FrameWork 2获取ServiceLocator In Form并填充 @timdev 的下拉列表,向我指出了描述'正确'方法的ZF2文档.我仔细地遵循了这一点,但我怀疑他们必须留下明显的代码,因为我可以填补空白,因为我无法让它工作.谁能看到我做错了什么?
我从一个表单开始,我添加了一个字段集:
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'
));
Run Code Online (Sandbox Code Playgroud)
}}
然后我创建了fieldset:
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',
),
),
));
}
Run Code Online (Sandbox Code Playgroud)
}
如您所见,我将PropertyType依赖项注入字段集.在这个阶段,我甚至没有使用它来生成options数组.我已对数组值进行了硬编码,以避免添加其他可能的错误源.一旦我得到要呈现的表单,我将尝试从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);
}
)
);
}
Run Code Online (Sandbox Code Playgroud)
}
此代码直接来自文档.我试过添加
return $fieldset;
Run Code Online (Sandbox Code Playgroud)
到PropertyFieldset工厂,我甚至尝试过添加
'invokables' => array(
'PropertyFieldset' => 'Ctmm\Form\PropertyFieldset'
)
Run Code Online (Sandbox Code Playgroud)
到getFormElementConfig数组,以及用invokable替换工厂.
最后一步是使用表单元素管理器在我的控制器操作中创建表单:
public function addAction() {
$formManager = $this->serviceLocator->get('FormElementManager');
$form = $formManager->get('Ctmm\Form\AddPropertyForm');
}
Run Code Online (Sandbox Code Playgroud)
无论我做什么,我都会收到错误消息,说Servicemanager无法创建PropertyFieldset:
Zend的\的ServiceManager \异常\ ServiceNotFoundException的
文件:
/home/mike/public_html/ctmm/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:456
Run Code Online (Sandbox Code Playgroud)
信息:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for PropertyFieldset
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
#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)
Run Code Online (Sandbox Code Playgroud)
AddPropertyForm.php中的第33行是我尝试添加自定义PropertyFieldset的地方.很明显,我在fieldset本身或我声明它的方式中有错误.我试过没有注入PropertyType依赖项,但这没有区别.为了完整性,我的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;
}
Run Code Online (Sandbox Code Playgroud)
}
编辑:
我没有答案,但我做了一些调查.我直接在控制器中创建了一个fieldset来测试我的PropertyFieldset类及它的依赖模型.
$property_type = $this->getServiceLocator()->get('Ctmm\Model\PropertyType');
$fieldset = new PropertyFieldset($property_type);
Run Code Online (Sandbox Code Playgroud)
这不会立即起作用.首先,我必须从Fieldset构造函数中提取出来
public function __construct(PropertyFieldset $property_type) {
Run Code Online (Sandbox Code Playgroud)
成为
public function __construct($property_type) {
Run Code Online (Sandbox Code Playgroud)
然后我不得不补充一下
parent::__construct('propertyfieldset');
Run Code Online (Sandbox Code Playgroud)
在它允许我添加元素之前.
一旦我添加了这些更改,我就能够在控制器中创建一个PropertyFieldset对象.我可以通过var_dump()来测试它.
不幸的是,对PropertyFieldset类的这些更改并没有解决基本问题,因此当我尝试在控制器中创建表单时,它会生成与以前相同的错误.我有,至少免除了PropertyFieldset类和它的依赖模型,它告诉我在Module.php类的getFormElementConfig()中有错误
所以我通过一些小的改动来解决这个问题:
正如您所指出的,PropertyFieldSet应该像这样调用父项构造:
parent::__construct('propertyfieldset');
Run Code Online (Sandbox Code Playgroud)
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;
},
)
);
}
Run Code Online (Sandbox Code Playgroud)
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',
));
}
}
Run Code Online (Sandbox Code Playgroud)
我们使用init()而不是使用__construct.当工厂实例化时,显然会调用此函数: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
),
));
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助 :)
| 归档时间: |
|
| 查看次数: |
4635 次 |
| 最近记录: |