Symfony2: Eco JSON Da un Controller per l’Uso in un ExtJS 4 Griglia

Ho appena iniziato con Symfony2 e sto cercando di capire quale sia l’approccio corretto è per vedere fuori JSON da un controller (ad esempio, People) per l’uso in un ExtJS 4 griglia.

Quando stavo facendo il tutto con un alla vaniglia MVC approccio, il mio controller avrebbe metodo chiamato qualcosa come getList che si chiama l’ People modello getList metodo, prendere i risultati e fare qualcosa di simile a questo:

<?php
class PeopleController extends controller {
    public function getList() {
        $model = new People();
        $data = $model->getList();
        echo json_encode(array(
            'success' => true,
            'root' => 'people',
            'rows' => $data['rows'],
            'count' => $data['count']
        ));
    }
}
?>
  • Che cosa fa questo tipo di comportamento simile in Symfony2?
  • È il controller il posto giusto per questo tipo di comportamento?
  • Quali sono le migliori pratiche (in un raggio di Symfony) per risolvere questo tipo di problema?

 

6 Replies
  1. 12

    È il controller il posto giusto per questo tipo di comportamento?

    Sì.

    Che cosa fa questo tipo di comportamento simile in Symfony2?

    Quali sono le migliori pratiche (in un raggio di Symfony) per risolvere questo tipo di problema?

    In symfony sembra molto molto simili, ma ci sono un paio di sfumature.

    Vi voglio proporre il mio approccio per questa roba. Partiamo dal routing:

    # src/Scope/YourBundle/Resources/config/routing.yml
    
    ScopeYourBundle_people_list:
        pattern:  /people
        defaults: { _controller: ScopeYourBundle:People:list, _format: json }

    Il _format parametro non è obbligatorio, ma vedremo in seguito perché è importante.

    Ora diamo un’occhiata al controller

    <?php
    //src/Scope/YourBundle/Controller/PeopleController.php
    namespace Overseer\MainBundle\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
    
    class PeopleController extends Controller
    {   
      public function listAction()
      {
        $request = $this->getRequest();
    
        //if ajax only is going to be used uncomment next lines
        //if (!$request->isXmlHttpRequest())
          //throw $this->createNotFoundException('The page is not found');
    
        $repository = $this->getDoctrine()
              ->getRepository('ScopeYourBundle:People');
    
        //now you have to retrieve data from people repository.
        //If the following code looks unfamiliar read http://symfony.com/doc/current/book/doctrine.html
        $items = $repository->findAll();
        //or you can use something more sophisticated:
        $items = $repository->findPage($request->query->get('page'), $request->query->get('limit'));
        //the line above would work provided you have created "findPage" function in your repository
    
        //yes, here we are retrieving "_format" from routing. In our case it's json
        $format = $request->getRequestFormat();
    
        return $this->render('::base.'.$format.'.twig', array('data' => array(
          'success' => true,
          'rows' => $items,
          //and so on
        )));
      }
      //...
    }    

    Controller esegue il rendering dei dati nel formato che è impostato nella configurazione di routing. Nel nostro caso è il formato json.

    Qui è un esempio di un possibile modello:

    {# app/Resourses/views/base.json.twig #}
    {{ data | json_encode | raw }}

    Il vantaggio di questo approccio (intendo utilizzando _format) è che se si decide di passare da json, per esempio, xml che non c’è problema, basta sostituire _format in configurazione di routing e, naturalmente, creare template corrispondente.

    • Fa questo lavoro? Non serializzare / json_encode la dottrina entità…
    • In realtà l’ho fatto. Vedere l’ultimo blocco di codice {{ data | json_encode | raw }}
  2. 8

    Vorrei evitare di usare un template per visualizzare i dati come la responsabilità per la fuga di dati, ecc quindi nel modello. Invece io uso integrato json_encode funzione in PHP molto come hai suggerito.

    Impostare il percorso per il controller di routing.yml come suggerito nella risposta precedente:

    ScopeYourBundle_people_list:
    pattern:  /people
    defaults: { _controller: ScopeYourBundle:People:list, _format: json }

    L’unica ulteriore passo è quello di forzare la codifica della risposta.

    <?php
    class PeopleController extends controller {
        public function listAction() {
            $model = new People();
            $data = $model->getList();
            $data = array(
                'success' => true,
                'root' => 'people',
                'rows' => $data['rows'],
                'count' => $data['count']
            );
            $response = new \Symfony\Component\HttpFoundation\Response(json_encode($data));
            $response->headers->set('Content-Type', 'application/json');
            return $response;
        }
    }
    ?>
    • Solo una piccola nota a margine, se il percorso specificare il _format l’opzione corretta, il Content-Type intestazione è impostato automaticamente da Symfony2, come può essere visto in Response classe qui. Dal momento che, in questo esempio, il formato è json, il Content-Type intestazione con il valore 'application/json' verrà aggiunto alla risposta.
  3. 1

    Invece di costruire la vostra risposta è inoltre possibile utilizzare il built-in JsonResponse.

    Si definisce il percorso come nelle altre risposte suggerite:

    ScopeYourBundle_people_list:
    pattern:  /people
    defaults: { _controller: ScopeYourBundle:People:list, _format: json }

    E utilizzare il nuovo tipo di risposta:

    <?php
    class PeopleController extends controller {
        public function listAction() {
            $model = new People();
            $data = $model->getList();
            $data = array(
                'success' => true,
                'root' => 'people',
                'rows' => $data['rows'],
                'count' => $data['count']
            );
            return new \Symfony\Component\HttpFoundation\JsonResponse($data);
        }
    }

    Per ulteriori informazioni, vedere la api o il doc (versione 2.6).

Lascia un commento