具有最后一个数组元素的表单集合
Form collection with last array element
我有两个实体:Issue 和 Notes,一个问题可以有多个注释。我这样定义它们:
class Issue {
// ...
/**
* @ORM\OneToMany(targetEntity="Note", mappedBy="issue")
*/
protected $notes;
public function getNotes() {
return $this->notes->toArray();
}
public function addNote($note) {
if (!$this->notes->contains($note)) $this->notes->add($note);
}
public function removeNote($note) {
if ($this->notes->contains($note)) $this->notes->removeElement($note);
}
}
class Note {
// ...
/**
* @ORM\Column(type="string", nullable=false)
*/
protected $description;
/**
* @ORM\ManyToOne(targetEntity="Issue", inversedBy="notes")
* @ORM\JoinColumn(name="issue", referencedColumnName="id", nullable=false)
*/
protected $issue;
public function getDescription() // ...
public function setDescription() // ...
public function getIssue() // ...
public function setIssue() // ...
}
我定义了一个 IssueType 来创建一个嵌入 NoteType 表单的表单:
class IssueType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
// ...
->add('notes', 'collection', ['type' => new NoteType()]);
}
}
class NoteType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('description', 'textarea');
}
}
当我想创建一个新问题时这很有效,因为笔记数组只包含一个由 IssueController 创建的(空白)笔记,用户可以使用表单填写它。但是,一旦创建了问题,我就有了一个显示所有注释的视图问题页面,并且在底部有一个用于添加新注释的表单。问题是收集表单为新的(空白)笔记以及所有以前的笔记创建了一个输入(见下图)。
有什么方法可以让我使用 Symfony 只包含新的(空白)笔记表单的输入,或者我是否需要使用 JavaScript 删除以前的笔记?
编辑:
这是 IssueController 的代码:
public function newAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$issue = new Issue();
$note = new Note();
$issue->addNote($note);
$note->setIssue($issue);
$form = $this->createForm('issue', $issue);
$form->handleRequest($request);
// ...
if ($form->isValid()) {
$em->persist($issue);
$em->persist($note);
$em->flush();
return $this->redirectToRoute(...);
}
return $this->render('/issue/new.html.twig', [
'issue' => $issue,
'form' => $form->createView()
]);
}
出现注释编辑框是因为您的表单指示为一对多关系创建一个可编辑的集合。将某些内容放入表单类型意味着它通常是可编辑的,或者至少以表单形式呈现。
如果您希望您的表单只能添加新注释,则必须删除该表单的集合 属性。
而不是
->add('notes', 'collection', ['type' => new NoteType()]);
有
->add('newNote', 'textarea', ['label' => 'Add note', 'mapped' => false];
您的控制器也需要修改。
public function newAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$issue = new Issue();
$form = $this->createForm('issue', $issue);
$form->handleRequest($request);
if ($form->isValid()) {
if ($newNote = trim($form['newNote']->getData())) {
$note = new Note();
$issue->addNote($note);
$note->setIssue($issue);
$note->setDescription($newNote);
$em->persist($note); // Probably not needed as you're cascading persist
}
$em->persist($issue);
$em->flush();
return $this->redirectToRoute(...);
}
return $this->render('/issue/new.html.twig', [
'issue' => $issue,
'form' => $form->createView()
]);
}
这只会显示新笔记的输入。要显示现有笔记,您需要在视图中执行此操作,例如:
<h2>Notes</h2>
{% for note in issue.notes if note.description %}
<p>{{ loop.index }}: {{ note.description }}</p>
{% else %}
<p>No notes have been added for this issue.</p>
{% endfor %}
我有两个实体:Issue 和 Notes,一个问题可以有多个注释。我这样定义它们:
class Issue {
// ...
/**
* @ORM\OneToMany(targetEntity="Note", mappedBy="issue")
*/
protected $notes;
public function getNotes() {
return $this->notes->toArray();
}
public function addNote($note) {
if (!$this->notes->contains($note)) $this->notes->add($note);
}
public function removeNote($note) {
if ($this->notes->contains($note)) $this->notes->removeElement($note);
}
}
class Note {
// ...
/**
* @ORM\Column(type="string", nullable=false)
*/
protected $description;
/**
* @ORM\ManyToOne(targetEntity="Issue", inversedBy="notes")
* @ORM\JoinColumn(name="issue", referencedColumnName="id", nullable=false)
*/
protected $issue;
public function getDescription() // ...
public function setDescription() // ...
public function getIssue() // ...
public function setIssue() // ...
}
我定义了一个 IssueType 来创建一个嵌入 NoteType 表单的表单:
class IssueType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
// ...
->add('notes', 'collection', ['type' => new NoteType()]);
}
}
class NoteType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('description', 'textarea');
}
}
当我想创建一个新问题时这很有效,因为笔记数组只包含一个由 IssueController 创建的(空白)笔记,用户可以使用表单填写它。但是,一旦创建了问题,我就有了一个显示所有注释的视图问题页面,并且在底部有一个用于添加新注释的表单。问题是收集表单为新的(空白)笔记以及所有以前的笔记创建了一个输入(见下图)。
有什么方法可以让我使用 Symfony 只包含新的(空白)笔记表单的输入,或者我是否需要使用 JavaScript 删除以前的笔记?
编辑:
这是 IssueController 的代码:
public function newAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$issue = new Issue();
$note = new Note();
$issue->addNote($note);
$note->setIssue($issue);
$form = $this->createForm('issue', $issue);
$form->handleRequest($request);
// ...
if ($form->isValid()) {
$em->persist($issue);
$em->persist($note);
$em->flush();
return $this->redirectToRoute(...);
}
return $this->render('/issue/new.html.twig', [
'issue' => $issue,
'form' => $form->createView()
]);
}
出现注释编辑框是因为您的表单指示为一对多关系创建一个可编辑的集合。将某些内容放入表单类型意味着它通常是可编辑的,或者至少以表单形式呈现。
如果您希望您的表单只能添加新注释,则必须删除该表单的集合 属性。
而不是
->add('notes', 'collection', ['type' => new NoteType()]);
有
->add('newNote', 'textarea', ['label' => 'Add note', 'mapped' => false];
您的控制器也需要修改。
public function newAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$issue = new Issue();
$form = $this->createForm('issue', $issue);
$form->handleRequest($request);
if ($form->isValid()) {
if ($newNote = trim($form['newNote']->getData())) {
$note = new Note();
$issue->addNote($note);
$note->setIssue($issue);
$note->setDescription($newNote);
$em->persist($note); // Probably not needed as you're cascading persist
}
$em->persist($issue);
$em->flush();
return $this->redirectToRoute(...);
}
return $this->render('/issue/new.html.twig', [
'issue' => $issue,
'form' => $form->createView()
]);
}
这只会显示新笔记的输入。要显示现有笔记,您需要在视图中执行此操作,例如:
<h2>Notes</h2>
{% for note in issue.notes if note.description %}
<p>{{ loop.index }}: {{ note.description }}</p>
{% else %}
<p>No notes have been added for this issue.</p>
{% endfor %}