我试图建立一个负责在我的数据库中注册食品的表格。对于每种产品,我还要注册产品包装上的成分。
对于这两个实体,我有以下两个类:
成分:
class Ingredient {
// ...
/**
* @var string
*
* @Assert\NotBlank()
* @Assert\Type("string")
*
* @ORM\Column(name="name", type="string", length=255, unique=false)
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="NutritionBundle\Entity\Product", mappedBy="ingredients")
*/
private $products;
// ...
public function __toString() {
return $this->getName();
}
/**
* Set name
*
* @param string $name
*
* @return Ingredient
*/
public function setName( $name ) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
// ...
/**
* @return Product
*/
public function getProducts() {
return $this->products;
}
/**
* @param Product $products
*
* @return Ingredient
*/
public function setProducts( Product $products ) {
$this->products = $products;
return $this;
}
// ...
}
产品:
class Product {
// ...
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
// ...
/**
* @ORM\ManyToMany( targetEntity="NutritionBundle\Entity\Ingredient", inversedBy="products" )
* @ORM\JoinTable(name="ingredients_products")
*/
private $ingredients;
// ...
public function __construct() {
$this->ingredients = new ArrayCollection();
}
// ...
/**
* Set name
*
* @param string $name
*
* @return Product
*/
public function setName( $name ) {
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName() {
return $this->name;
}
// ...
/**
* @return mixed
*/
public function getIngredients() {
return $this->ingredients;
}
/**
* @param mixed $ingredients
*
* @return Product
*/
public function setIngredients( $ingredients ) {
$this->ingredients = $ingredients;
return $this;
}
// ...
}
然后,在树枝方面,我需要创建表单并使用Select2来存档以下内容:
目前,我为产品表单执行的ProductType
课程如下所示:
class ProductType extends AbstractType {
public function buildForm( FormBuilderInterface $builder, array $options ) {
$builder
->add( 'name' )
->add( 'company' )
->add( 'front_picture' )
->add( 'back_picture' )
->add( 'weight' )
->add( 'unit' )
->add( 'barcode' )
->add( 'product_url' )
->add( 'ingredients' );
// ->add(
// 'ingredients',
// EntityType::class,
// array(
// 'class' => 'NutritionBundle\Entity\Ingredient',
// 'choice_label' => function ( $ingredient ) {
// return sprintf(
// '%2$s [E%1$s]',
// $ingredient->getCode(),
// $ingredient->getName()
// );
// },
// 'choice_value' => 'id',
// 'multiple' => true,
// )
// );
// $builder->get( 'ingredients' )->addModelTransformer( $this->ingredients_transformer );
}
public function configureOptions( OptionsResolver $resolver ) {
$resolver->setDefaults(
array(
'data_class' => 'NutritionBundle\Entity\Product',
)
);
}
public function getBlockPrefix() {
return 'nutritionbundle_product';
}
}
正如您在注释掉的代码中所看到的,我也尝试了EntityType
选项,但可能无法满足我的要求。
最后在树枝上我有Ingredients
字段的以下代码:
<div
class="form-group {% if product_form.ingredients.vars.errors|length %}has-error{% endif %}"
>
<label
for="{{ product_form.ingredients.vars.id }}"
class="control-label"
>
Ingredients
</label>
<select
name="{{ product_form.ingredients.vars.full_name|e('html_attr') }}"
id="{{ product_form.ingredients.vars.id }}"
multiple="multiple"
class="form-control"
data-values="{{ product_form.ingredients.vars.value|join(',') }}"
></select>
<span class="help-block">
<small>Enter the product ingredients as they appear in the ingredients list.</small>
</span>
{% if product_form.ingredients.vars.errors|length %}
<span class="help-block">
{{ form_errors( product_form.ingredients ) }}
</span>
{% endif %}
</div>
我必须以这种方式呈现Ingredients
字段的原因是为了实现仅使用AJAX加载已经分配给给定产品的成分所需的定制。
最后,最后一个问题是,由于这个自定义字段渲染,Symfony仍使用默认控件呈现Ingredients
字段:
如您所见,按钮上方是我自定义的渲染字段,按钮下方是Symfony强制使用的字段。
在我目前的形式状态下,如果我尝试创建在DB中尚未存在的新成分,我会收到错误,因为成分不在数据库中,并且当然不能指定它们到产品。
答案 0 :(得分:1)
要不再渲染Ingredients
字段,可以使用
{% do product_form.ingredients.setRendered %}
但我建议你使用 https://github.com/tetranz/select2entity-bundle
然后您不需要阻止渲染。使用该Bundle,您必须在控制器中定义远程路由,该路由将返回选项列表。