2012-02-24 39 views
2

我需要原型內原型的一些幫助。 Symfony在生成表單原型時非常聰明,但是一旦你下了一層(即原型內的原型),它就會重用$$ name $$作爲原型。

這是我的實體原型字段的樣子。 JQuery使用正確的索引值(根據子節點的數量)換出$$ $$ $$。

<input type="text" id="entry_entities_$$name$$_contactFax" name="entry[entities][$$name$$][contactFax]" value="" /> 

迄今爲止這麼好。但是,當你去更深一層,Symfony的使用$$名$$一個新的水平調得太低 - 這裏是爲實體屬性的原型:

<div id="entry_entities_123_properties" data-prototype="  
    &lt;label for=&quot;entry_entities_$$name$$_properties_$$name$$_name&quot;&gt;Name&lt;/label&gt; 
    &lt;input type=&quot;text&quot; id=&quot;entry_entities_$$name$$_properties_$$name$$_name&quot; name=&quot;entry[entities][$$name$$][properties][$$name$$][name]&quot; value=&quot;&quot; /&gt; 

這意味着,(在這個例子中,實體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完整的例子如何解決這個問題?我開始在每一行上尋找/替換第二個$$ $$,但是非常混亂。我確信有一個簡單的方法可以做到這一點,但我無法在互聯網上找到任何指南。

+0

你在prototype()函數中傳遞'$$ name $$',你不能在那裏改變它嗎? – meze 2012-02-24 09:41:58

+2

其實我在發帖之後看了一下Symfony的代碼。 $$ $$被硬編碼到CollectionType中。看看Symfony \ Component \ Form \ Extension \ Core \ Type \ CollectionType.php – mogoman 2012-02-24 09:48:22

+2

對。 [未在2.1中硬編碼](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php)。 – meze 2012-02-24 09:56:48

回答

5

此代碼是爲symfony1.2 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的集合,但使用原型pe_name參數。

+0

完美,非常感謝! – mogoman 2012-02-24 10:37:40

+0

3天后,我看到這個答案嘗試重寫和區分佔位符。我希望我早點看到它。 +10000000! – renoirb 2013-01-26 00:36:10

+0

@renoirb好!但請記住這是2.0的破解。從v2.1開始,您只需將名稱傳遞給'prototype()'函數即可。 – meze 2013-01-26 05:44:47

0

我對Symfony並不熟悉,但在Javascript中使用String.replace()只會替換默認情況下的第一個匹配項,所以您可以非常安全地使用它。

$('mydiv').html 
(
    $('mydiv').html().replace('$$name$$', 123).replace('$$name$$', 456); 
); 

如果事情分離到不同的線路,並且希望在這些線路更換,你可以使用.split()把它分解成一個數組,for()了它,那麼它.join()重新走到一起。

+0

感謝您的答案 - 我相信您的想法可行,但結果會是很多Javascript。 Meze的答案符合Symfony2最佳實踐。 – mogoman 2012-02-24 10:40:12

+0

足夠公平:)主要作爲一個選項發佈,希望有人提出一個Symfony相關的解決方案。很高興你有一種方式,你很滿意 – Joe 2012-02-24 10:43:56