ZF2: предварительно заполнить данные набора полей

У меня проблема с моим набором полей в Zend Framework 2. Пользователь может сохранять свои личные данные через форму. Если он уже сохранил это, они должны быть предварительно заполнены данными из базы данных. Это работало нормально, так как это была только форма, но мне нужны адресные данные в наборе полей, чтобы я мог использовать их в других частях моей программы. Теперь поля ввода остаются пустыми.

Сначала я заполняю личные данные в сеансе. Мои данные выглядят так:

object(Application\Model\Product\PersonalData)#247 (3) { 
    ["tel":protected]=> string(0) "" 
    ["birthday":protected]=> string(10) "2013-01-01" 
    ["address":protected]=> object(Application\Model\Account\Addresses)#248 (15) {    
        ["firstname":protected]=> string(5) "Ernie" 
        ["surname":protected]=> string(6) "Muppet"    
        ...
    } 
} 

Как вы можете видеть, данные уже привязаны к заданным объектам, PersonalData в качестве основного и адреса для набора полей. Кажется, это работает тогда. Затем я положил это в моей форме:

$oForm->setData($oForm->getHydrator()->extract($_SESSION->getPersonalData()));
return new ViewModel(array('form'=>$oForm));

У addressFieldset есть гидратор и привязка, которая работает, потому что все объекты идеально заполнены. Единственная проблема в том, что когда я открываю страницу, поля ввода пусты, заполняются только день рождения и телефон, которые находятся прямо в форме

Моя форма реализует набор полей адреса следующим образом:

$addressFieldset = new AddressFieldset($lang);
$addressFieldset->setUseAsBaseFieldset(true);
$addressFieldset->setName('address');
$this->add($addressFieldset);

Я думаю, что это может быть просто проблема с правильной адресацией моего набора полей, но я не могу объяснить, почему он будет заполнен правильно после публикации данных. Все, что я хочу, это чтобы он заполнил setData в моем Fieldset.

Я надеюсь, что вы понимаете мой вопрос и могли бы помочь мне.
Большое спасибо,
Svenja

РЕДАКТИРОВАТЬ: Я проанализировал это немного больше сейчас, это очень странно, и я не знаю, что пошло не так. Когда я отлаживаю, я вижу, что $fieldset->getValue() возвращает все данные, которые мне нужны. Поэтому я подумал, что привязка может быть неправильной, и я сделал это, чтобы отладить шаг за шагом:

$values = $this->form->get('address')->getValue();
$addressFieldset = $this->form->get('address');
$aValues = $addressFieldset->getHydrator()->extract($values);
$addressFieldset->bindValues($aValues);

Я пошел в Fieldset.php и bindValues ​​отлично выполняет то, что должен (в любом случае это всего лишь перепросмотр (?)), Вызывает гидратор и заполняет мой объект. Но если я покажу в элементах, все значения равны NULL. Я уже проверил свои элементы дважды. Единственное различие между моделью и элементами - это другой порядок объявления. Я также вызываю метод setUseAsBaseField(true) в наборе полей и в форме. Я не могу понять, почему данные в значениях, но не в элементах.

2 ответа

Решение

Я наконец нашел решение! Сначала мне помогла эта ссылка: Заполнение наборов полей Я не интегрировал входной фильтр набора полей в фильтр ввода формы.
Но это было не все, что я должен сделать. Моя форма-датамодель выглядит так:

interface IPersonalData
{
    public function getTel();
    public function getBirthday();
    public function getAddress();

    public function setTel($tel);
    public function setAddress(IAddresses $address);
    public function setBirthday($birthday);
}

Это только интерфейс, но Address - это объект. И это проблема. Когда форма пытается заполнить набор полей, он принимает только массивы. Поэтому я должен извлечь свой объект в методе getter в массив. Я не думаю, что это очень полезно, потому что я обычно хочу получить свой объект с помощью этого метода. Поэтому я пишу метод "getAddressAsArray()", который выглядит следующим образом:

public function getAddressAsArray()
{
    $oAddressHydrator = new AddressHydrator();
    if(isset($this->address))
    {
        return $oAddressHydrator->extract($this->address);
    }
    return array();
}

Метод извлечения моего гидратора изменился следующим образом:

public function extract($object)
{
    if(!$object instanceof IPersonalData)
    {
        throw new \InvalidArgumentException('$object must be an instance of Application\Model\Product\IPersonalData');
    }
    return array(
        'telephone' => $object->getTel(), 
        'address' => $object->getAddressAsArray(),
        'birthday' => $object->getBirthday(),
    );
}

Это очень странно, потому что у меня есть что-то, и это хорошо работает. Вы уверены, что выражение $_SESSION->getPersonalData() вернет желаемый результат? Вы используете очень странный сеанс. http://framework.zend.com/manual/2.1/en/modules/zend.session.container.html

РЕДАКТИРОВАТЬ (извините, мой английский):

  1. Вы можете использовать различные типы гидратора, например ArraySerializable (по умолчанию ваша сущность должна иметь методы getArrayCopy() и exchangeArray(), в вашем случае) ArraySerializable является гидратором по умолчанию.
  2. Сначала вы должны связать форму с помощью сущности $form->bind(new Entity()); Объект будет привязан к базовому набору полей. Если базовый набор полей не указан, объект будет связываться с формой, поскольку форма наследует набор полей. Если объект является агрегатом, т. Е. Его свойства содержат другие объекты, для каждого из этих объектов должен быть свой набор файлов. В конструкторе это дочерние наборы полей вы должны использовать $this->setObject(new MyChildrenEntity()); В результате свойства сущности будут извлечены в элементы формы.
  3. После этого вы должны работать только с формой, но не с ее элементами или наборами полей.
  4. Вы можете передавать любые данные в форме, поэтому элементы формы получат эти значения. $ Форма-> УстановитьДанные ($this-> GetRequest()->getPost()); Этот метод использует внутренний метод populateValues ​​(). Если в форме есть элементы с соответствующим именем, им будут присвоены эти значения. Если форма имеет наборы полей, они также будут перенесены в эти значения.
  5. Пока форма не может быть проверена, объект этих значений не будет назначен. Эти значения присваиваются объектам только в случае успешной проверки. Метод IsValid () использует внутренний метод bindValues ​​(), если проверка прошла успешно.
  6. После успешной проверки вы можете получить сущность, используя метод getData () $ entity = $ form-> getData ();

PS: Если вы делаете сложный "хак", не обижайтесь на это простое объяснение.

Другие вопросы по тегам