Я новичок в среде Zend и пытаюсь заполнить поле выбора в наборе полей в форме. Я перешел по разным ссылкам, но ни одна из них не увенчалась успехом.
У меня есть две таблицы Item & Category, идентификатор категории существует как внешний ключ в таблице элементов. Я пытаюсь загрузить доступные категории для выбора в режиме редактирования или добавления.
Я использовал их в качестве базы
Как запустить фабрику наборов полей в ZF3
ZF3 - Заполнить выбор из базы данных
Фабрика полевых наборов
class ItemFieldsetFactory implements FactoryInterface {
public function __invoke(ContainerInterface $container, $requestedName, array $options = null) {
$category = $container->get(CategoryRepository::class);
$categories = $category->findAllCategoriesAsArray();
$fieldset = $container->get('FormElementManager')->get(\Form\ItemFieldset::class);
$fieldset->setCategories($categories);
return $fieldset;
}
}
Набор полей
namespace Item\Form;
use Zend\Form\Fieldset;
use Zend\Form\Element\Select;
use Item\Model\Item;
use Zend\Hydrator\ReflectionHydrator as ReflectionHydrator;
class ItemFieldset extends Fieldset
{
private $categories = [];
public function setCategories(array $categories) {
$this->categories = $categories;
}
public function init()
{
$this->setHydrator(new ReflectionHydrator());
$this->setObject(new Item('', '', '', ''));
$this->add([
'type' => 'hidden',
'name' => 'itemid',
]);
$this->add([
'type' => Select::class,
'name' => 'categoryid',
'options' => [
'label' => 'Category',
'value_options' => $this->categories
]
]);
$this->add([
'type' => 'text',
'name' => 'description',
'options' => [
'label' => 'Description',
],
]);
$this->add([
'type' => 'text',
'name' => 'size',
'options' => [
'label' => 'Size',
],
]);
}
}
Фабрика контроллеров
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$formManager = $container->get('FormElementManager');
return new WriteController(
$container->get(ItemCommandInterface::class),
$formManager->get(ItemForm::class),
$formManager->get(ItemFieldset::class),
$container->get(ItemRepositoryInterface::class)
);
}
}
Контроллер
{
private $command;
private $form;
private $fieldset;
private $repository;
/**
* @param ItemCommandInterface $command
* @param ItemForm $form
*/
public function __construct(
ItemCommandInterface $command,
ItemForm $form,
ItemFieldset $fieldset,
ItemRepositoryInterface $repository
) {
$this->command = $command;
$this->form = $form;
$this->fieldset = $fieldset;
$this->repository = $repository;
}
public function addAction()
{
$req = $this->getRequest();
$viewModel = new ViewModel(['form' => $this->form]);
if (! $req->isPost()) {
return $viewModel;
}
$this->form->setData($req->getPost());
if (! $this->form->isValid()) {
return $viewModel;
}
$item = $this->form->getData();
try {
$item = $this->command->insertItem($item);
} catch (\Exception $ex) {
// An exception occurred; we may want to log this later and/or
// report it to the user. For now, we'll just re-throw.
throw $ex;
}
return $this->redirect()->toRoute(
'item/detail',
['itemid' => $item->getItemId()]
);
}
Конфигурация
namespace Item;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\Form;
use Zend\Fieldset;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'service_manager' => [
..
],
'controllers' => [
..
],
'router' => [
..
],
'form_elements' => [
'factories' => [
Form\ItemFieldset::class => Factory\ItemFieldsetFactory::class
]
],
'view_manager' => [
'template_path_stack' => [
__DIR__ . '/../view',
],
],
];
Я надеялся, что поле выбора будет содержать все доступные категории (в режиме редактирования с выбранной текущей).
Все, что я получаю, это пустая коробка
Я думаю, что мой ItemFieldsetFactory не срабатывает, но не могу понять, почему. Моя причина этого в том, что я пытался остановиться на этом этапе, вызвав несуществующий метод, а также с помощью vardump & exit.
Любые советы / рекомендации с благодарностью.
also by vardump & exit
ой. Если вы занимаетесь локальной разработкой, следуйте этому руководству от Jetbrains или это с Docker. - Использование xdebug сэкономит вам невероятное количество времени на размещение этихvar_dump($var);exit;
строк, обновление, проверку, редактирование и повторение, вместо этого предоставив вам возможность остановить выполнение, проверить во время выполнения и протестировать изменения во время выполнения. - person rkeet   schedule 19.07.2019$this->setHydrator(new ReflectionHydrator()); $this->setObject(new Item('', '', '', ''));
, сделайте это на своей фабрике с помощью$fieldsetVar->setHydrator((new Hydrator())->setObject(new Category());
. Если это не может измениться, вы могли бы также, поскольку это ничего не меняет для логики создания содержимого набора полей (что вы делаете в классе) - person rkeet   schedule 19.07.2019$categories
представляет собой массив только значений, вы должны иметь значения в виде текстовых опций и числовые ключи в качестве опций значений в выводе HTML. Если вы определили пары ключ/значение, они должны присутствовать. ЕслиfindAllCategoriesAsArray
возвращает массив объектов, вам необходимо преобразовать их, возможно, с помощью анонимной функции при настройке элемента Select. Вы можете подтвердить свою ситуацию по этому поводу? - person rkeet   schedule 19.07.2019'value_options' => $here,
должен иметь массив ключ/значение вместо$here
. Таким образом,['foo' => 'bar', 'space' => 'astronaut'']
дает 2 варианта (1 - значение «foo» с текстом «bar», 2 значение «пробел» с текстом «астронавт»). - person rkeet   schedule 22.07.2019