コレクションタイプを別のコレクションタイプ内に含めたい。次のようになります。
コレクションを1つだけ使用しても問題ありませんが、外側のフォームのプロトタイプを編集する必要があるため、各行の内側のフォームのプロトタイプがレンダリングされます。
どうすればそれを行うことができますか?また、保存する最良の方法は何でしょうか
編集:今私はネストされたフォームのプロトタイプをレンダリングしようとしています:
<ul class="characteristics-container" data-prototype="{{ form_widget(form.characteristics.vars.prototype)|e }}" data-prototype-options="{{ form_widget(form.characteristics.options.vars.prototype|e ) }}">
{# iterate over each existing tag and render its only field: name #}
{% for characteristic in form.characteristics %}
<li>{{ form_row(characteristic.name) }}</li>
<div class="characteristics-options">
{% for opt in form.characteristics.options %}
{% endfor %}
</div>
{% endfor %}
</ul>
form_widget(form.characteristics.options.vars.prototype|e
でエラーが発生します
Method "options" for object "Symfony\Component\Form\FormView" does not exist in
私は特性[0]を試しました、そしてそれはキーが存在しないと言います
ここに私のフォームクラスがあります:
PromotionType(基本形式)
$builder
->add('characteristics','collection', array(
'label' => 'Caracteristicas',
'type' => new PromotionCharacteristicType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
))
PromotionCharacteristicType
$builder
->add('name',NULL, array('label' => 'Nome'))
->add('options', 'collection', array(
'type' => new PromotionCharacteristicOptionType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'by_reference' => false,
))
;
PromotionCharacteristicOptionType
$builder
->add('name',NULL, array('label' => 'Nome'))
;
最初のレベルのプロトタイプは正常に動作します。
異なるコレクションの2つのプロトタイプを保持する必要があります。 symfonyはそれらをdivタグのdata-prototype属性に格納することを提案し、コレクションをラップします。あなたの状況では、それは非常に非効率的です。だからあなたはそれを空のdivのどこかに手動でレンダリングすることができます
キャラクターフォームの例
class CharacterType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('opts', 'collection', array(
'type' => new OptionType(),
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'prototype_name' => '__opt_prot__'
));
$builder->add('char_desc', 'text');
}
public function getName()
{
return 'char';
}
}
次に、文字コレクションを含むフォームを作成します
$form = $this->createFormBuilder()
->add('chars', 'collection', array(
'type' => new CharacterType(),
'allow_add' => true,
'allow_delete' => true,
'prototype_name' => '__char_prot__'
))
->getForm();
# example data
$form->setData(
array(
'chars' => array(
array('options' => array(), 'char_desc' => 1),
array('options' => array(), 'char_desc' => 2),
),
)
);
プロトタイプを取得します
<div
id="prots"
data-prototype-opt="{{ form_widget(form.chars.vars.prototype.children['opts'].vars.prototype) | e }}"
data-prototype-char="{{ form_widget(form.chars.vars.prototype) | e }}"
>
</div>
そして、このようにコレクションをレンダリングします 例 またはcollection_widgetブロックをオーバーライドします
{% for char in form.chars %}
{{ form_row(char.char_desc) }}
<label for="">opts</label>
{% for opt in char.opts %}
{{ form_row(opt.text) }}
{% endfor %}
{% endfor %}
可能であれば、nosqlデータベースを使用してください。または、関係データベースに対して [〜#〜] eav [〜#〜] モデルを使用します。しかし、オプションを検索したり、並べ替えたりする必要がない場合は、シリアル化された配列をデータベースに保存し、doctrine type array
Alexey B。 の答えに追加すると、通常、コレクションのプロトタイプにアクセスできるようにするためにprototype.children['opts']
を使用する必要はないようです。次のようにprototype.<collection_name>
を使用します。
<div
id="prots"
data-prototype-opt="{{ form_widget(form.chars.vars.prototype.opts.vars.prototype) | e }}"
data-prototype-char="{{ form_widget(form.chars.vars.prototype) | e }}"
>
</div>