Symfony2 如何过滤查询

Symfony2 how to filter query

更新

我想我可能在这里偏离了方向,但我仍然得到相同的结果,整个页面都显示在 table。

所以我对视图和状态页面都这样做。查看是显示所有活动警报的默认页面。状态是将显示过滤警报的页面。所以这些页面中的每一个都有一个控制器

public function viewAction()
{
    $repository = $this
        ->getDoctrine()
        ->getManager()
        ->getRepository('NickAlertBundle:Alert');

    $alerts = $repository->getAllActiveAlerts();

    return $this->render('NickAlertBundle:Page:view.html.twig', array(
        'alerts' => $alerts,
    ));
}

public function getActivatedAction(Request $request)
{
    $alertStatus = $request->request->get('status', 'active');
    $alerts = $this->getDoctrine()->getRepository('NickAlertBundle:Alert')->getAlertByStatus($alertStatus);

    return $this->render('NickAlertBundle:Page:status.html.twig', array("alerts"=>$alerts));
}

每个页面都有一个路由

NickAlertBundle_view:
    pattern:  /view-alerts
    defaults: { _controller: NickAlertBundle:Alert:view }
    requirements:
       _method:  GET

NickAlertBundle_status:
    pattern:  /view-alerts
    defaults: { _controller: NickAlertBundle:Alert:getActivated }
    requirements:
       _method:  POST

NickAlertBundle_view 调用视图操作并呈现包含所有活动警报的页面。 NickAlertBundle_status 调用 getActivated 操作。

这两种观点相同,内容如下

{% extends 'NickAlertBundle::layout.html.twig' %}

{% block main %}

    <div class="col-md-12">

<section class="panel panel-default">
    <header class="panel-heading">
        <h3 class="panel-title">View Alerts</h3>
        <select name="alerts" id="alerts" data-url="{{ path('NickAlertBundle_status') }}">
            <option value="active">Active</option>
            <option value="inactive">Inactive</option>
        </select>
    </header>
    <div class="panel-body">

        <div class="row" id="alert-container">
            <table width="100%" cellpadding="0" cellspacing="0" border="0" id="datatable" class="table">
                <thead>
                <tr>
                    <th>Id</th>
                    <th>Search Command</th>
                    <th>Flight Number</th>
                    <th>Booking Class</th>
                    <th>Alert Pseudo</th>
                    <th>Alert Status</th>
                </tr>
                </thead>
                <tbody>
                    {% for alert in alerts %}
                        <tr>
                            <td>{{ alert[0].id }}</td>
                            <td>{{ alert[0].searchCommand }}</td>
                            <td>{{ alert.flight_number }}</td>
                            <td>{{ alert.classes }}</td>
                            <td>{{ alert.pseudos }}</td>
                            <td>{{ alert[0].alertStatus }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</section>
    </div>

{% endblock %}

所以数据url应该调用状态路由。两个视图都有这个,因为它们应该始终能够更改任一页面上的 select。

然后 javascript 和你给我看的几乎一样。


已更新


问题基本上是您嵌入了来自 viewAction 的 html 响应,而您实际上必须放置警报代码,例如:

public function getActivatedAction(Request $request)
{
    $alertStatus = $request->request->get('status', 'active');
    $alerts = $this->getDoctrine()->getRepository('NickAlertBundle:Alert')->findAllByStatus($alertStatus);

    return $this->render('NickAlertBundle:Alerts:show.html.twig', array("alerts"=>$alerts));
}

NickAlertBundle:Alerts:show.html.twig

{# NickAlertBundle:Alerts:show.html.twig #}
{% for alert in alerts %}
    <tr>
        <td>{{ alert[0].id }}</td>
        <td>{{ alert[0].searchCommand }}</td>
        <td>{{ alert.flight_number }}</td>
        <td>{{ alert.classes }}</td>
        <td>{{ alert.pseudos }}</td>
        <td>{{ alert[0].alertStatus }}</td>
    </tr>
{% endfor %}

那么在你的 NickAlertBundle:Page:view.html.twig 中:

$('#alerts').change(function(){
    $.ajax({
        type: "POST",
        url: $('#alerts').attr('data-url'), # getActivatedAction route
        data:{ status: $(this).val() },
        success: function(data){
            $('#alert-container table tbody').html(data);
        }
    });
});


您可以在实体存储库文件中添加一个方法:

# src/Package/AppBundle/Entity/AlertRepository.php
<?php

namespace Package\AppBundle\Entity;

use Doctrine\ORM\EntityRepository;

/**
 * AlertRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class AlertRepository extends EntityRepository
{
  public function findAllByStatus($status = "active")
  {
    $qb = $this->createQueryBuilder('a');
    $query = $qb
        ->where(
          $qb->expr()->eq('a.alertStatus', $status)
        )
        ->orderBy('a.id', 'DESC')
        ->getQuery();
    return $query->getResult();
  }

}

然后在您的控制器中,您可以传递 json 和数据或 html:

<?php
...
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
...

public function getActivatedAction(Request $request)
{
    $alertStatus = $request->request->get('status', 'active');
    $alerts = $this->getDoctrine()->getRepository('AppBundle:Alert')->findAllByStatus($alertStatus);

    // With JSON
    $json = alerts->toJson() // your own method

    $response = new JsonResponse();
    $response->setData($json);

    // With HTML
    return $this->render('AppBundle:Alerts:show.html.twig', array("alerts"=>$alerts));
}

现在在您的 html 文件中,您可以使用 ajax 请求警报:

<select name="alerts" id="alerts">
  <option value="active">Actives</option>
  <option value="inactive">Inactive</option>
</select>
<div id="alertsList"></div>

<script>
  $('#alerts').change(function(){
    $.ajax({
      type: "POST",
      url: "{{ path('alerts_getActivated') }}",
      data:{ status: $(this).val() },
      success: function(data){
          $('#alertsList').html(data); //Using the html response. With json you have to create the style and html here
      }
    });
  });
</script>

如果我没有遗漏任何东西,它应该会起作用。

如果我理解错了,请告诉我,希望这对你有所帮助。

$('#alert-container table tbody').html(data); 行将从服务器 return 的响应中设置你的 tbody table 的内容,所以你必须有两个不同的文件

{% NickAlertBundle:Page:view.html.twig %}
{% extends 'NickAlertBundle::layout.html.twig' %}

{% block main %}

    <div class="col-md-12">

<section class="panel panel-default">
    <header class="panel-heading">
        <h3 class="panel-title">View Alerts</h3>
        <select name="alerts" id="alerts" data-url="{{ path('NickAlertBundle_status') }}">
            <option value="active">Active</option>
            <option value="inactive">Inactive</option>
        </select>
    </header>
    <div class="panel-body">

        <div class="row" id="alert-container">
            <table width="100%" cellpadding="0" cellspacing="0" border="0" id="datatable" class="table">
                <thead>
                <tr>
                    <th>Id</th>
                    <th>Search Command</th>
                    <th>Flight Number</th>
                    <th>Booking Class</th>
                    <th>Alert Pseudo</th>
                    <th>Alert Status</th>
                </tr>
                </thead>
                <tbody>
                    {% for alert in alerts %}
                        <tr>
                            <td>{{ alert[0].id }}</td>
                            <td>{{ alert[0].searchCommand }}</td>
                            <td>{{ alert.flight_number }}</td>
                            <td>{{ alert.classes }}</td>
                            <td>{{ alert.pseudos }}</td>
                            <td>{{ alert[0].alertStatus }}</td>
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</section>
    </div>

{% endblock %}

{# NickAlertBundle:Page:status.html.twig #}
{% for alert in alerts %}
    <tr>
        <td>{{ alert[0].id }}</td>
        <td>{{ alert[0].searchCommand }}</td>
        <td>{{ alert.flight_number }}</td>
        <td>{{ alert.classes }}</td>
        <td>{{ alert.pseudos }}</td>
        <td>{{ alert[0].alertStatus }}</td>
    </tr>
{% endfor %}

要解决 url 问题,您应该输入:

NickAlertBundle_view:
    pattern:  /view-alerts
    defaults: { _controller: NickAlertBundle:Alert:view }
    methods:  [GET]

NickAlertBundle_status:
    pattern:  /view-alerts
    defaults: { _controller: NickAlertBundle:Alert:getActivated }
    methods:  [POST]