我需要一些有关原型内原型的帮助。 Symfony 在生成表单原型方面非常聪明,但是一旦你向下一层(即原型中的原型),它就会为两个原型重用 $$name$$ 。
这就是我的实体的原型字段的样子。 JQuery 将 $$name$$ 替换为正确的索引值(基于子节点的数量)
<input type="text" id="entry_entities_$$name$$_contactFax" name="entry[entities][$$name$$][contactFax]" value="" />
到目前为止一切顺利。但是当你更深入一层时,Symfony 也会使用 $$name$$ 来表示下一层 - 这是实体属性的原型:
<div id="entry_entities_123_properties" data-prototype="
<label for="entry_entities_$$name$$_properties_$$name$$_name">Name</label>
<input type="text" id="entry_entities_$$name$$_properties_$$name$$_name" name="entry[entities][$$name$$][properties][$$name$$][name]" value="" />
这意味着(在此示例中,实体 ID 为 123)所有属性都获得 ID 123:
name="entry[entities][123][properties][123][name]"
name="entry[entities][123][properties][123][name]"
name="entry[entities][123][properties][123][name]"
等等
在我看来,解决这个问题的最好方法是使用 $$somethingelse$$ 作为属性 - 有谁知道这是在哪里设置的 - 或者有没有人有一个完整的 JS 示例来解决这个问题?我开始对每行第二个 $$name$$ 进行可怕的查找/替换,但它变得非常混乱。我确信有一种简单的方法可以做到这一点,但我在互联网上找不到任何指南。
此代码适用于 symfony 2.0(在 2.1+ 中,您可以将名称传递给
prototype()
函数):
您可以使用所需选项创建自己的集合类型:
<?php
namespace YourBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\EventListener\ResizeFormListener;
use Symfony\Component\Form\Extension\Core\Type\CollectionType as BaseCollectionType;
class CollectionType extends BaseCollectionType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilder $builder, array $options)
{
if ($options['allow_add'] && $options['prototype']) {
$prototype = $builder->create($options['prototype_name'], $options['type'], $options['options']);
$builder->setAttribute('prototype', $prototype->getForm());
}
$listener = new ResizeFormListener(
$builder->getFormFactory(),
$options['type'],
$options['options'],
$options['allow_add'],
$options['allow_delete']
);
$builder
->addEventSubscriber($listener)
->setAttribute('allow_add', $options['allow_add'])
->setAttribute('allow_delete', $options['allow_delete'])
;
}
/**
* {@inheritdoc}
*/
public function getDefaultOptions(array $options)
{
$defaultOptions = parent::getDefaultOptions($options);
$defaultOptions['prototype_name'] = '$$name$$';
return $defaultOptions;
}
}
然后只需定义一个服务:
tags:
- { name: form.type, alias: collection }
并将其用作 Symfony 的集合,但带有prototype_name参数。
我不熟悉 Symfony,但在 Javascript 中使用
String.replace()
默认情况下仅替换第一个出现的位置,因此您可以非常安全地使用它。
$('mydiv').html
(
$('mydiv').html().replace('$$name$$', 123).replace('$$name$$', 456);
);
如果内容被分成不同的行,并且您想在这些行中进行替换,则可以使用
.split()
将其分解为数组,然后 for()
覆盖它,然后 .join()
将其重新组合在一起。