我一直在研究一个Symfony2项目已有一段时间了,虽然我认为我正在正确地执行这个特定的部分,但它并不是我需要它的工作方式。
我在与任务及其所在类别相关的树枝模板上显示数据。这使用连接表,因为它是一个ManyToMany关系,因为任务可以分配给多个类别。幸运的是,只有3个类别,所以它不太复杂。
目前,我循环遍历分配给每个任务的类别,如此...在此示例中,'task'是从任务实体检索的数据,其中'category'是映射到连接表的数组集合:
{% for cat in task.category %}
<input type="checkbox" checked name="cat[]" /><label>{{ cat.name }}</label>
{% endfor %}
如您所见,有一个复选框列表,并且要检查分配给该任务的类别。以上代码仅显示已分配的类别。
要获得所有类别,我做了:
{% for category in categories %}
...
{% endfor %}
其中“categories”是Category实体的findAll()结果。
基本上,我需要做的是遍历所有可用的类别,但只检查分配的类别。我尝试创建一个可以交叉引用的数组:
{% for cat in stage.category %}
{% set arr = {} %}
{% for category in categories %}
{% set arr = arr|merge({ 'id': cat.id}) %}
{% endfor %}
{% if category.id in arr %}
...
{% endif %}
{% endfor %}
但是数组中只有一个值,因为我认为它只是覆盖它。因此,如果任务仅分配给一个类别,这很好,但不幸的是,它可以分配给几个。
我需要的是循环查看类别并运行检查以查看它是否已分配给当前任务的方法。
我也试过删除数组选项并使用它:
{% for cat in stage.category %}
{% for category in categories %}
{% if cat.id == category.id %}
<input id="category_{{ category.id }}" checked type="checkbox" name="category[]" />
<label style="font-weight:100" for="category_{{ category.id }}">{{ category.name }}</label><br />
{% else %}
<input id="category_{{ category.id }}" type="checkbox" name="category[]" />
<label style="font-weight:100" for="category_{{ category.id }}">{{ category.name }}</label><br />
{% endif %}
{% endfor %}
{% endfor %}
但这只会显示所有类别两次,一次检查,一次未选中。
我是以正确的方式接近这个吗?或者有更好,更简单的方法吗?
希望有人能指出我正确的方向。
修改
感谢您的回答 - 问题是,为了执行所提供的解决方案,某些数据无法直接访问,但我对此有很多想法并想出了这个:
// get all the active categories for each task
foreach($tasks as $task) {
foreach($task->getCategory() as $task_category) {
$task_array[$task->getId()]['active'][$task_category->getId()] = $task_category->getName();
}
}
// get all available categories
foreach($categories as $category) {
$category_array[$category->getId()] = $category->getName();
}
// find out which categories are not in the active array and add them as inactive
foreach($task_array as $key => $task_cat) {
foreach($task_cat as $new_key => $new_task) {
foreach ($category_array as $cat_key => $cat_name) {
if (!array_key_exists($cat_key, $new_task)) {
$task_array[$key]['inactive'][$cat_key] = $cat_name;
}
}
}
}
然后,我有一个$ task_array,看起来像这样:
Array
(
[1] => Array
(
[active] => Array
(
[1] => Standard Wire Guide
[2] => Standard Wire Guide with Additional Features
)
[inactive] => Array
(
[3] => Stator
)
)
[2] => Array
(
[active] => Array
(
[1] => Standard Wire Guide
[2] => Standard Wire Guide with Additional Features
)
[inactive] => Array
(
[3] => Stator
)
)
....
);
现在我有一个可管理的数组,我可以在twig文件中使用。
感谢您的所有建议:)
答案 0 :(得分:2)
试一试。我认为这就是你要找的东西。它对我有用。
诀窍是将条件置于“已检查”属性。
//
// In our controller.
//
$categories =
[
['id' => 1, 'name' => 'catOne'],
['id' => 2, 'name' => 'catTwo'],
['id' => 3, 'name' => 'catThree']
];
$tasks =
[
['id' => 1, 'name' => 'Some task', 'cats' => [ 1, 3 ]],
['id' => 2, 'name' => 'Another task', 'cats' => [2]]
];
$vars = ['categories' => $categories, 'tasks' => $tasks];
Return $this->render( 'SiteBundle:Debug:debug.html.twig', $vars );
{#
# In the template.
#}
{% for task in tasks %}
{{ task.name }}:
{% for category in categories %}
<input id="category_{{ category.id }}"
type="checkbox"
{% if category.id in task.cats %}checked{% endif %}
name="category[]"/>
<label style="font-weight:100"
for="category_{{ category.id }}">{{ category.name }}</label>
{% endfor %}<br>
{% endfor %}
答案 1 :(得分:0)
我建议如下:
将以下方法添加到Catorgy
:
namespace MyBundle\Entity;
class Catorgy {
...
public function isAssigned()
{
return (count($this->getTasks()) > 0);
}
...
}
如果您的多对多关系已正确定义,则getTasks
方法已经存在或者不应该难以添加。
然后,在Twig中,只需MyClass::isSomething()
即可访问名为MyClass.something
的方法:
{% for cat in catorgies %}
<input id="category_{{ cat.id }}" type="checkbox" name="category[]"{% if cat.assigned %} checked{% endif %}/>
<label style="font-weight:100" for="category_{{ cat.id }}">{{ cat.name }}</label><br />
{% endfor %}
这是我能想到的最简单的方式。