我用MongoDB作为DB创建了一个小的Symfony2-Website(带有Symfony PR11)。 我可以创建一个使用普通文档的表单,但是如何使用带有embeddedDocument的文档?
这是文件:
/**
* @mongodb:Document(collection="location")
*/
class Location
{
/**
* @mongodb:Id
*/
protected $id;
/**
* @mongodb:String
*/
protected $locationName;
/**
* @mongodb:EmbedMany(targetDocument="LocationTerminal")
*/
protected $terminals = array();
// Setter
public function setTerminals(LocationTerminal $terminal)
{
array_push($this->terminals, $terminal);
}
public function setLocationName($locationName)
{
$this->locationName = $locationName;
}
// Getter
public function getId()
{
return $this->$id;
}
public function getLocationName()
{
return $this->locationName;
}
public function getTerminals()
{
return $this->terminals;
}
}
EmbeddedDocument:
/**
* @mongodb:EmbeddedDocument
*/
class LocationTerminal
{
/**
* @mongodb:String
*/
protected $terminalName;
/**
* @mongodb:Int
*/
protected $since;
/**
* @mongodb:Int
*/
protected $to;
// Setter
public function setTerminalName($terminalName)
{
$this->terminalName = $terminalName;
}
public function setSince($since)
{
$this->since = $since;
}
public function setTo($to)
{
$this->to = $to;
}
// Getter
public function getTerminalName()
{
return $this->terminalName;
}
public function getSince()
{
return $this->since;
}
public function getTo()
{
return $this->to;
}
}
正如您所看到的,$terminals
拥有EmbedMany
- 文件
这是表格:
class LocationForm extends Form
{
public function configure()
{
$this->add(new TextField('locationName', array('max_length' => 255, 'required' => true)));
}
public function addTerminals($dm)
{
$this->add(new ChoiceField('terminals.terminalName', array('choices' => $dm)));
$this->add(new DateField('terminals.since', array('required' => true)));
$this->add(new DateField('terminals.to', array('required' => false)));
}
}
使用过的Controller如下所示:
class LocationController extends Controller
{
protected $location;
protected $locationTerminal;
protected function getDm()
{
return $this->get('doctrine.odm.mongodb.document_manager');
}
protected function getLocation($name = null)
{
if ($name != null)
{
$dm = $this->getDm();
$this->location = $dm->getRepository('RalfBundle:Location')->findOneBy(array('locationName' => $name));
if (! $this->location)
{
$this->location = new Location();
$this->locationTerminal = new LocationTerminal();
$this->location->setLocation($name);
$this->location->setTerminals($this->locationTerminal);
}
}
else
{
$this->location = new Location();
$this->locationTerminal = new LocationTerminal();
$this->location->setTerminals($this->locationTerminal);
$this->locationTerminal->setSince(0);
$this->locationTerminal->setTerminalName("");
$this->locationTerminal->setTo(0);
}
}
protected function getForm()
{
$form = LocationForm::create($this->get('form.context'), 'location');
$dm = $this->getDm();
$form->addTerminals($dm->getRepository('RalfBundle:Terminal')->findAll()->toArray());
return $form;
}
//... some Actions
public function createAction()
{
$this->getLocation();
$form = $this->getForm();
$form->bind($this->get('request'), $this->location);
if ($form->isValid())
{
$dm = $this->getDm();
$dm->persist($this->location);
$dm->flush();
return $this->redirect($this->generateUrl('Location'));
}
return $this->render('RalfBundle:Ralf:location_create.html.twig', array('form' => $form));
}
我可以看到,locationName
收到表单中输入的值,但EmbedMany
- 数组terminals
仍为空。
我错了什么?
感谢您的帮助:D
好的,找到了解决方案。
public function addTerminals($dm)
LocationForm
中的应该如下所示:
public function addTerminals($dm)
{
$this->add(new ChoiceField('terminals.0.terminalName', array('choices' => $dm)));
$this->add(new DateField('terminals.0.since', array('required' => true, 'type'=> 'timestamp')));
$this->add(new DateField('terminals.0.to', array('required' => false, 'type' => 'timestamp')));
}
'type' => 'timestamp'
是必要的,因为DateField
会创建一个DateTime
- 对象,但文档需要Int
timestamp
。terminals
- 数组的字段可以通过普通的点符号访问。答案 0 :(得分:0)
好的,找到了解决方案。
public function addTerminals($dm)
LocationForm
中的应该如下所示:
public function addTerminals($dm)
{
$this->add(new ChoiceField('terminals.0.terminalName', array('choices' => $dm)));
$this->add(new DateField('terminals.0.since', array('required' => true, 'type'=> 'timestamp')));
$this->add(new DateField('terminals.0.to', array('required' => false, 'type' => 'timestamp')));
}
'type' => 'timestamp'
是必要的,因为DateField
会创建一个DateTime
- 对象,但文档需要Int
timestamp
。terminals
- 数组的字段可以通过普通的点符号访问。答案 1 :(得分:0)
Symfony 2实际上为您提供了一种处理表单中嵌入文档的工具:它被称为“collection field type”,它使您能够以父表单的形式嵌入其他表单类型(来自其他嵌入文档)。
它可以配置为允许/禁止添加/删除嵌入文档,实际上非常强大。