我在学说中有一对多的关系。我想统计每个相关的字段,并将它们显示在Twig中,用于循环
到目前为止
Vp与选民有关。Vp有许多选民,而选民有一个Vp我想统计每个Vp 的每个相关选民
public function getAllVp()
{
return $this
->createQueryBuilder('v')
->select('vp.id,COUNT(v.id) as num')
->from('Voters', 'v')
->join('v.Vp', 'vp')
->orderBy('v.id', 'ASC')
->getQuery()
->getResult()
;
}
我想要像一样的Twig
{% for vp in vps %}
{{ vp.firstname }}
{{ vp.num }}//number of voters
{% endfor %}
控制器
$vice_president = $em->getRepository('Bundle:Vp')->getAllVp();
return $this->render('Bundle:Vp:all_vp.html.twig', array(
'vps' => $vice_president,
));
条令
fields:
firstname:
type: string
length: 255
lastname:
type: string
length: 255
photo:
type: string
length: 255
oneToMany:
voters:
targetEntity: Voters
mappedBy: vp
我收到这个错误
[语义错误]第0行,第94列,靠近'vp,Voters v':错误:Class Project\Bundle\DutterBundle\Entity\vp没有名为vp 的关联
如何在学说中正确实现这一点?
更新
voters.orm.yml
manyToOne:
vp:
targetEntity: Vp
cascade: { }
mappedBy: null
inversedBy: voters
joinColumn:
name: vp_id
referencedColumnName: id
orphanRemoval: false
我可以通过简单地调用相关的"投票者"并在Twig中添加一个过滤器来实现这一点。但我的意图是在条令中计算数据,在其他模板中重用它,或者将来将其转换为json,例如在Angular JS 中
{% if vp.voters|length > 0 %}
<tr {% if loop.index is odd %}class="color"{% endif %}>
<td>{{ vp.id }}</td>
<td>{{ vp.getFullName() }}</td>
<td>{{ vp.voters|length|number_format }}</td>
</tr>
{% endif %}
上面是一个工作代码,但我想在条令中进行计数,而不是在模板中
预期结果
id fullname counts
1 George Bush 45
2 ali gail 1999
4 Mae Young 45
......
首先,您可以在Voter映射中删除mappedBy: null
。
面向PHP:
好的,你可以尝试这个PHP解决方案,在你的实体Vp中添加一个新方法,比如:
public function getVotersCount(){
return count($this->voters);
}
在你的树枝视图中,你可以做:
{{ vp.getVotersCount() }}
以条令为导向:(http://docs.doctrine-project.org/en/latest/reference/events.html#lifecycle-事件)
在您的Vp实体表单映射中:
fields:
firstname:
type: string
length: 255
lastname:
type: string
length: 255
photo:
type: string
length: 255
oneToMany:
voters:
targetEntity: Voters
mappedBy: vp
lifecycleCallbacks:
postLoad: [ countVotersOnPostLoad ]
还有一个新的属性,getter和countVoters方法:
protected $votersCount;
public function getVotersCount(){
return $this->votersCount;
}
public function countVotersOnPostLoad ()
{
$this->votersCount = count($this->voters);
}
在你看来,简单地做:
{{ vp.votersCount }}
我的工作是创建一个服务。
<?php
namespace ProjectBundleDutBundleTwig;
class AllVpExtension extends Twig_Extension
{
protected $em;
public function __construct($em)
{
this->em = $em;
}
public function getFunctions()
{
return array(
//this is the name of the function you will use in twig
new Twig_SimpleFunction('number_votes_vp', array($this, 'b'))
);
}
public function getName()
{
//return 'number_employees';
return 'vp_app_extension';
}
public function b($id)
{
$qb=$this->em->createQueryBuilder();
$qb->select('count(v.id)')
->from('DutBundle:Voters','v')
->join('v.vp','c')
->where('c.id = :x')
->setParameter('x',$id);
$count = $qb->getQuery()->getSingleScalarResult();
return $count;
}
}
现在,为了统计每个vp的相关选民,我可以呼叫服务并将结果发送到trick
public function all_vpAction()
{
$em = $this->getDoctrine()->getManager();
$vice_president = $em->getRepository('DutBundle:Vp')->findAll();
//communicate to service container
$data = $this->container->get('duterte.twig.vp_app_extension');
$datas = array();
foreach ($vice_president as $value) {
$datas[] = array('id' => $value->getId(),'firstname' => $value->getFirstname() . ' ' . $value->getLastname(),'numbers' => (int)$data->b($value->getId()));
}
$vice = $datas;
return $this->render('DutBundle:Vp:all_vp.html.twig', array(
'vps' => $vice,
));
//or we can wrap this in json
$serializer = $this->container->get('jms_serializer');
$jsonContent= $serializer->serialize($vice,'json');
return $jsonContent;
}
有了这个设置,我可以将其封装到json中,并使用自定义的twig过滤器,我可以显示以Angular或纯twig模板排序的数据,或者同时显示
顺便说一下,我的观点
{% extends '::base.html.twig' %}
{% block body %}
{% block stylesheets %}
{{ parent() }}
<style type="text/css">
#img-responsive{
height: 320px;
/*width: 300px;*/
}
</style>
{% endblock %}
<div class="section-heading">
<h2>Best Tandem Of the Day</h2>
</div>
<div class="row">
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="/img/dut.jpg" id="img-responsive">
<div class="caption">
<h3>President</h3>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="thumbnail">
<img src="/img/unknown.jpg" id="img-responsive">
<div class="caption">
<h3>Vice-President</h3>
</div>
</div>
</div>
</div>
<hr />
<div ng-app="myApp" ng-controller="customersCtrl">
Search Here: <input type="text" placeholder="search" ng-model="searchMe"/><br />
<table class="table">
//names//
<thead>
<tr>
<th>Full Name</th>
<th>Middlename</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in names">
<td>//x.id//</td>
<td>//x.firstname//</td>
<td>//x.numbers//</td>
</tr>
</tbody>
</table>
</div>
<div class="table-responsive">
<table class="table table-hover table-bordered table-condensed" id="table1">
<thead>
<tr>
<th>#</th>
<th>Bet</th>
<th>Votes</th>
<!--th>Photo</th-->
</tr>
</thead>
<tbody>
{% for v in vps | sortbyfield('numbers') %}
{% if v.numbers > 0 %}
<tr>
<td>{{ v.id }}</td>
<td>{{ v.firstname }}</td>
<td>{{ v.numbers }}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script src="//code.angularjs.org/1.4.8/angular.js"></script>
<script>
var app = angular.module('myApp', []);
app.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//');
$interpolateProvider.endSymbol('//');
});
app.controller('customersCtrl',['$scope','$http',function($scope, $http) {
$http.get("{{ path('vp_president') }}")
.success(function (response) {
$scope.names= JSON.parse(response);
});
</script>
{% endblock %}