Đầu tiên tôi đã đọc tài liệu cho cả hai Collection Field Type và How to Embed a Collection of Forms ... Ví dụ này là về một thực thể (Tác vụ) có quan hệ một-nhiều với thực thể khác (Tag), và tôi hiểu nó, nhưng tôi không thể thích nghi nó với những gì tôi muốn!Cách tạo biểu mẫu có nhiều hàng của một thực thể trong Symfony2
Để làm cho nó đơn giản hơn, chúng ta hãy nói rằng tôi có một tổ chức công tác, thực hiện nhiệm vụ này có một số mối quan hệ với các đối tượng khác như người dùng và dự án (mỗi nhiệm vụ có thể có một người dùng và một dự án)
Tôi muốn làm một hình thức, bên trong mẫu đơn này một danh sách các nhiệm vụ, mỗi nhiệm vụ trong một hàng của một bảng hiển thị thông tin như task.title, task.startdate, task.user.name, task.user.company.name, task.project.name và có 2 trường có thể chỉnh sửa được, hộp văn bản " Mô tả " và hộp kiểm" đang hoạt động ". Bạn có thể chỉnh sửa nhiều tác vụ và gửi biểu mẫu bằng một nút ở cuối bảng trong biểu mẫu chính, vì vậy về cơ bản bạn có thể cập nhật nhiều bản ghi trong một giao dịch (thay vì tạo một biểu mẫu và một nút gửi cho mỗi hàng và một bản cập nhật cho mỗi lần gửi).
Tôi có rất nhiều vấn đề với thiết kế phức tạp này:
Trước tiên tôi muốn làm theo mẫu để nhúng một tập hợp các hình thức bên trong các hình thức chính, Vì vậy, tôi đã thực hiện một loại mẫu cho công tác của tôi rằng nên giống như một hình thức mỗi hàng. Tôi đã thực hiện những tập tin này:
Mẫu Kiểu cho công tác:
// src/Acme/TaskBundle/Form/Type/TaskType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TaskType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('description', 'text', ['label' => false, 'required' => false, 'attr' => ['placeholder' => 'description']]);
$builder->add('active', 'checkbox', ['label' => false, 'required' => false, 'data' => true]);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TaskBundle\Entity\Task',
));
}
public function getName()
{
return 'taskType';
}
}
Mẫu Kiểu cho hình thức chính:
// src/Acme/TaskBundle/Form/Type/SaveTasksType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Acme\TaskBundle\Form\Type\TaskType.php;
class SaveTasksType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('tasksCollection', 'collection', ['type' => new TaskType()]);
$builder->add('tasksSubmit', 'submit', ['label' => 'Save']);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
'attr' => ['class' => 'form-horizontal'],
'method' => 'POST'
]);
}
public function getName()
{
return 'saveTasksType';
}
}
Nhiệm vụ Mẫu Bộ điều khiển:
// src/Acme/TaskBundle/Controller/ManageTasksController.php
namespace Acme\TaskBundle\Controller;
use Acme\TaskBundle\Entity\Task;
use Acme\TaskBundle\Form\Type\SaveTaskType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ManageTasksController extends Controller
{
public function showListAction(Request $request)
{
$repository = $this->getDoctrine()->getRepository('ExampleBundle:Task');
$tasks = $repository->findAll();
$taskSaveForm = $this->createForm(new SaveTasksType(['tasks' => $tasks]));
return $this->render('AcmeTaskBundle:Task:list.html.twig', array(
'taskSaveForm' => $taskSaveForm->createView(),
));
}
}
công tác Mẫu Twig Template (chỉ là một phần liên quan):
<div class="innerAll">
{{ form_start(taskSaveForm) }}
{{ form_errors(taskSaveForm) }}
<table class="table table-bordered table-striped table-primary list-table">
<thead>
<tr>
<th>Task ID</th>
<th>Title</th>
<th>Start Date</th>
<th>User</th>
<th>Company</th>
<th>Project</th>
<th>Description</th>
<th>Active</th>
</tr>
</thead>
<tbody>
{% for task in taskSaveForm.tasksCollection %}
<tr>
<td>{{ task.id }}</td>
<td><a href="https://localhost/taskid={{ task.id }}">{{ task.title }}</a></td>
<td>{{ task.startDate }}</td>
<td>{{ task.userName }}</td>
<td>{{ task.companyName }}</td>
<td>{{ task.projectName }}</td>
<td>{{ form_widget(task.description) }}</td>
<td>{{ form_widget(task.active) }}</td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
<div>{{ form_row(taskSaveForm.tasksSubmit) }}</div>
{{ form_end(taskSaveForm) }}
</div>
NHƯNG có một vấn đề ở đây, khi tôi nhận được kết quả từ xây dựng truy vấn nó là một mớ hỗn độn của mảng chứa các đối tượng trong họ, tôi nhận được một lỗi về
Dữ liệu chế độ xem của biểu mẫu được mong đợi là một thể hiện của lớp Acme \ TaskBundle \ Entity \ Task, nhưng là một mảng (n). Bạn có thể tránh lỗi này bằng cách đặt tùy chọn "data_class" thành null hoặc bằng cách thêm trình biến đổi chế độ xem biến đổi mảng (n) thành một phiên bản của Acme \ TaskBundle \ Entity \ Task.
Đây là truy vấn:
createQueryBuilder()
->select(
"
task.id,
task.title,
task.startDate,
task.description,
user.name as userName,
company.name as companyName,
project.name as projectName,
"
)
->from('Acme\TaskBundle\Entity\Task', 'task')
->innerJoin('task.project', 'project')
->innerJoin('task.user', 'user')
->innerJoin('Acme\TaskBundle\Entity\Company', 'company', 'with', 'store.company = company')
->where('task.active = :isActive')->setParameter('isActive', true);
Soooo, tôi sử dụng Partial Objects dẫn để xem nếu nó có thể giúp đỡ, nó giúp để làm cho đối tượng nhiệm vụ trong kết quả truy vấn và tôi có thể giải nén nó và gửi nó để hình thành, nhưng vẫn có vẻ như phần còn lại của hình thức là không biết phần còn lại của các đối tượng ...
Ok, vì vậy có thể tôi đang chọn cách tiếp cận sai, tôi không chắc chắn! xin vui lòng nếu bạn có bất cứ đề nghị về những gì tôi nên làm, đặt một lưu ý ở đây ... Tôi đang đấu tranh với điều này trong hơn một tuần! Cảm ơn trước cho thời gian của bạn! Ngay cả khi bạn không đặt bất kỳ ghi chú nào, tôi đánh giá cao việc bạn dành thời gian đọc câu hỏi rất dài của tôi! Cảm ơn! :)
Xin lỗi vì tôi đã không trả lại cho bạn! Chuỗi nhiệm vụ của tôi đã thay đổi nên tôi đang làm việc trên các nội dung khác ngay bây giờ ... Tôi sẽ liên hệ lại với bạn và sẽ cho bạn biết nếu nó hoạt động! Tôi có một ý tưởng từ câu trả lời của bạn, và tôi hy vọng nó hoạt động! cảm ơn vì đã dành thời gian và gửi câu trả lời ... :) – Monica
Xin lỗi vì đã kiểm tra câu trả lời của bạn với một sự chậm trễ lớn! Câu trả lời của bạn đã giúp tôi rất nhiều, tôi sẽ chấp nhận câu trả lời của bạn! :) Tôi cũng sẽ cập nhật câu hỏi của riêng mình sau, với phiên bản cuối cùng! – Monica
Không phải lo lắng về sự chậm trễ. Vui mừng nó đã giúp. – geoB