我目前正在使用Symfony2重新構建Web應用程序。我希望用戶更新他們在我們的MySQL數據庫上的特定記錄。但是,用戶對計算機用戶並不自信,並且不喜歡Web應用程序(以其當前形式)的工作方式。 因此,從UI/UX的角度來看,我決定使用2種形式來編輯特定的數據,而不是用戶不喜歡的當前1形式。如何在Symfony2中將表單保存到數據庫中,而不是實體
有問題的MySQL數據庫表包含許多信息領域,例如他們的個人信息和與他們相關的其他信息。表單被分割以反映這一點,其中一個表單更新個人細節,一個表單更新其餘表單,因此用戶不必處理一個長表單。
此刻雖然,當我去使用一個形式,我得到的錯誤:
The class 'Symfony\Component\Form\Form' was not found in the chain configured namespaces during Form Submission
此錯誤是在這個question解決。但是,這給我留下了一個問題。目前,由於我將表單分成兩部分,因此我無法將此數據保存到數據庫。我可以通過使用一種形式來克服這一點,但這違背了數據庫用戶的意願。此外,我知道完全有可能使用兩種或更多種形式將特定數據添加到單個數據庫,就像我之前完成的那樣,而不是在Symfony中。
有誰知道,或有建議,我該如何克服這一點?由於當前數據量龐大,因此更改數據庫不存在問題。
UPDATE
這裏是缺少視圖,控制器並形成文件。
view.html.twig
<!-- Modal Windows: Edit Instructor Personal Details -->
<div id="editPersonal" style="display:none;">
<div class="modal-head">
<h2>Edit Personal Details For: <font-color="red !important">{{instructor.firstName}} {{instructor.surname}}</font></h2>
</div>
<div class="modal-body">
<form action="#" method="post" {{ form_enctype(ipde) }} id="editPersonalDetails" class="modaledit">
<table class="modalform-col1">
<tbody>
<tr class="hidden">
<th>{{ form_label(ipde.id, 'ID*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.id) }}
{{ form_widget(ipde.id, { 'attr': {'class': 'textfield'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.firstName, 'First Name*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.firstName) }}
{{ form_widget(ipde.firstName, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.surname, 'Surname*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.surname) }}
{{ form_widget(ipde.surname, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.address1, 'Address Line 1*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.address1) }}
{{ form_widget(ipde.address1, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.address2, 'Address Line 2', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.address2) }}
{{ form_widget(ipde.address2, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.town, 'Town*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.town) }}
{{ form_widget(ipde.town, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.county, 'County*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.county) }}
{{ form_widget(ipde.county, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.postcode, 'Postcode*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.postcode) }}
{{ form_widget(ipde.postcode, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ipde.email, 'Email*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ipde.email) }}
{{ form_widget(ipde.email, { 'attr': {'class': 'text'}}) }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<div class="modal-placeright">
<a href="#close" rel="modal:close" class="closebutton">Close Without Saving</a>
<input type="submit" value="Save Changes" id="savebuttonpr" class="savebutton" />
{{ form_rest(ipde) }}
</div>
</div>
</div>
DefaultController.php
<?php
namespace PCUK\InstructorBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use PCUK\InstructorBundle\Form\IpdeType;
use PCUK\InstructorBundle\Form\IrType;
use PCUK\InstructorBundle\Form\BaType;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function viewAction($instructor, Request $request)
{
// Database connection
$insrep = $this->getDoctrine()->getManager();
// Get Instructor from Entity for Form use
$instructorQ = $insrep->getRepository('InstructorBundle:MapInstructors')->find($instructor);
// Get Shared Branches from Entity for Form use
$instructorS = $insrep->getRepository('InstructorBundle:MapInstructorShared')->find($instructor);
// Generate Form to edit Instructor Personal Details
$ipde = $this->createForm(new IpdeType(), $instructorQ);
// Handle Form submission to edit Instructor Personal Details
if ($request->getMethod() == 'POST') {
$ipde->bind($request);
if ($ipde->isValid()) {
// perform some action, such as saving the task to the database
//if ($this->request->isXmlHttpRequest()){
//return data ajax requires.
//}
$em = $this->getDoctrine()->getManager();
$em->persist($ipde);
$em->flush();
return $this->redirect($this->generateUrl('task_success'));
}
}
// Generate Form to edit Instructor Records
$ir = $this->createForm(new IrType(), $instructorQ);
// Generate Form to edit Instructor Records
$ba = $this->createForm(new BaType(), $instructorS);
// Return data to view
return $this->render('InstructorBundle:Default:view.html.twig', array(
'ipde' => $ipde->createView(),
'ir' => $ir->createView(),
'ba' => $ba->createView()
));
}
}
IpdeType.php - 個人資料表格
<?php
// src/PCUK/InstructorBundle/Form/Type/IpdeType.php
// This is to handle forms for the Instructor Personal Details Form
namespace PCUK\InstructorBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FileField;
class IpdeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('id', 'integer', array('required'=>false));
//Personal Details
$builder->add('firstName', 'text', array('required'=>false));
$builder->add('surname', 'text', array('required'=>false));
$builder->add('address1', 'text', array('required'=>false));
$builder->add('address2', 'text', array('required'=>false));
$builder->add('town', 'text', array('required'=>false));
$builder->add('county', 'text', array('required'=>false));
$builder->add('postcode', 'text', array('required'=>false));
$builder->add('email', 'text', array('required'=>false));
$builder->add('phone', 'text', array('required'=>false));
$builder->add('mobile', 'text', array('required'=>false));
$builder->add('notes', 'text', array('required'=>false));
}
public function getName()
{
return 'ipde';
}
}
IrType.php - 其他信息表
<?php
// src/PCUK/InstructorBundle/Form/Type/IrType.php
// This is to handle forms for the Instructor Records Form
namespace PCUK\InstructorBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FileField;
class IrType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('id', 'integer', array('required'=>false));
$builder->add('primaryArea', 'integer', array('required'=>false));
$builder->add('primaryBranch','entity', array('class'=>'PCUK\InstructorBundle\Entity\MapBranches', 'property'=>'branchname'));
$builder->add('begin', 'date', array('required'=>false));
$builder->add('lastCrb', 'date', array('required'=>false));
$builder->add('latestCpd', 'date', array('required'=>false));
$builder->add('preferredLevel','entity', array('class'=>'PCUK\InstructorBundle\Entity\MapInstructorLevels', 'property'=>'name'));
$builder->add('preferredDiscipline','entity', array('class'=>'PCUK\InstructorBundle\Entity\MapInstructorLevels', 'property'=>'name'));
$builder->add('currentLevel','entity', array('class'=>'PCUK\InstructorBundle\Entity\MapInstructorLevels', 'property'=>'name'));
$builder->add('bhs', 'checkbox', array('required'=>false));
$builder->add('visiting','entity', array('class'=>'PCUK\InstructorBundle\Entity\MapInstructorVis', 'property'=>'name'));
}
public function getName()
{
return 'ir';
}
}
更新:29/04/13 繼james_t的建議,我在兩個,每個分別形式拆分實體。但是,原始錯誤仍然存在。
我也在控制器中創建了一個新的操作,並且由於拆分實體沒有解決問題,我恢復爲使用單個實體。我現在控制器看起來如下:
的viewAction 公共職能的viewAction($講師,請求$請求) {// 數據庫連接 $ insrep = $這個 - > getDoctrine() - > getManager();
// Get IPDE from Entity for Form use
$instructorIpde = $insrep->getRepository('InstructorBundle:MapInstructors')->find($instructor);
// Generate Form to edit Instructor Personal Details
$ipde = $this->createForm(new IpdeType(), $instructorIpde);
// Get IR from Entity for Form use
$instructorIr = $insrep->getRepository('InstructorBundle:MapInstructors')->find($instructor);
// Generate Form to edit Instructor Records
$ir = $this->createForm(new IrType(), $instructorIr);
// Get Shared Branches from Entity for Form use
$instructorBa = $insrep->getRepository('InstructorBundle:MapInstructorShared')->find($instructor);
// Generate Form to edit Instructor Records
$ba = $this->createForm(new BaType(), $instructorBa);
// Return data to view
return $this->render('InstructorBundle:Default:view.html.twig', array(
'pagename' => $iname . ' - Instructors',
'ipde' => $ipde->createView(),
'ir' => $ir->createView(),
'ba' => $ba->createView(),
'iid' => $instructor
));
}
ipdeAction
公共函數ipdeAction($指導員,請求$請求) { //數據庫連接 $ insrep = $這 - > getDoctrine() - > getManager();
// Get IPDE from Entity for Form use
$instructorIpde = $insrep->getRepository('InstructorBundle:MapInstructors')->find($instructor);
// Generate Form to edit Instructor Personal Details
$ipde = $this->createForm(new IpdeType(), $instructorIpde);
// Handle Form submission to edit Instructor Personal Details
if ($request->getMethod() == 'POST') {
$ipde->bind($request);
if ($ipde->isValid()) {
// perform some action, such as saving the task to the database
//if ($this->request->isXmlHttpRequest()){
//return data ajax requires.
//}
$em = $this->getDoctrine()->getManager();
$em->persist($ipde);
$em->flush();
$params = array(
'instructor' => $instructor,
);
return $this->redirect($this->generateUrl('instructor_viewinstructor', $params));
}
}
}
我也修正了這個更新,我view.html.twig文件:
<form action="#" method="post" {{ form_enctype(ipde) }} id="editPersonalDetails" class="modaledit">
這樣:
<form action="{{ path('instructor_viewinstructor_ipde', {'instructor' :iid}) }}" method="post" {{ form_enctype(ipde) }} id="editPersonalDetails" class="modaledit">
我的路由。 yml文件現在看起來也是這樣:
instructor_viewinstructor:
pattern: /instructors/view/{instructor}
defaults: { _controller: InstructorBundle:Default:view }
instructor_viewinstructor_ipde:
pattern: /instructors/view/{instructor}/ipde
defaults: { _controller: InstructorBundle:Default:ipde }
requirements:
_method: POST
表單和控制器的代碼將會很有幫助。表單是單獨編輯還是一個接一個地進行編輯(如設置嚮導)? – 2013-04-25 09:42:13
對不起,知道有些事我忘了!我已經將它們添加到了那裏,供您查看。 – mickburkejnr 2013-04-25 09:50:31
當你說數據庫,你的意思是表?將Native Queries與Doctrine一起使用並讀取請求變量沒有什麼問題,它只是更多的代碼,但是它可以工作。另外,表單不需要實體。這聽起來像你有一個顯示問題,只需使用[嵌入窗體](http://symfony.com/doc/current/book/forms.html#embedding-a-single-object),然後使用你的模板來製作它'容易'爲您的用戶。 – 2013-04-25 17:54:49