Twig和条令-统计每个相关实体并在Twig循环中显示



我在学说中有一对多的关系。我想统计每个相关的字段,并将它们显示在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 %}

最新更新