2009-09-30 9 views
7

Voy a comenzar un proyecto utilizando una implementación de Zend Framework MVC.MVC: ¿cómo ajax?

¿Cómo trabajo con ajax? Quiero decir, ¿debería colocar todo el código Ajax en el controlador? ¿O a la vista?

Por ejemplo, quiero obtener publicaciones del autor 'ivan' para mostrar en una página.

Normalmente, creo un enlace a '/ posts/author/ivan' o algo así, creo una nueva Acción como 'byAuthorAction()' en el controlador Posts (o quizás en el controlador de Users, donde sea), visualícela (y todo el código que obtiene las publicaciones del modelo va allí) y crea una nueva Ruta hacia él.

Cómo agregar funcionalidades para obtener las publicaciones de cualquier usuario en formato json, xml para ajax y tal vez API, manteniendo el principio DRY y diseñando la estructura de código lo más inteligente que pueda?

-

¡Gracias por responder! Estaré muy contento de ver comentarios sobre el diseño de MVC en situaciones como la mía. Tengo cierta experiencia en principios básicos de MVC, pero no en casos más complicados. Tal vez algunos enlaces útiles?

Respuesta

13

que realmente debería leer el capítulo del manual sobre ContextSwitch ayudante de acciones. Pero aquí es un breve resumen:

  • sus scripts de vista (acción-name.phtml) se utilizan para la salida HTML normal
  • puede inicializar un cambio de contexto para algunas acciones en el controlador pues creían puede dar salida, por ejemplo, XML - xml context es compatible por defecto y usted pondría su script de vista para el contexto xml en (nombre-acción.xml.phtml); El contexto xml también deshabilita la representación del diseño
  • json también es compatible con el conmutador de contexto integrado y la opción predeterminada es deshabilitar tanto el diseño como la vista y generar todas las variables asignadas a la vista desde la acción del controlador en formato JSON , esta opción se puede alternar utilizando el método setAutoJsonSerialization (false) del cambio de contexto; pero si lo cambia debe crear un script de vista nombre-acción.json.phtml y muestra las variables en formato JSON a mano

Para cambiar entre estos dos contextos, debe agregar un parámetro de formato a su URL, p./posts/author/ivan/format/json o/posts/author/ivan/format/xml. Si no especifica el formato, su aplicación generará html sin formato.

Versión especial del conmutador de contexto es AjaxContext y también tiene que configurar éste a mano. No utiliza el parámetro 'formato' para identificar qué formato debe usar para el resultado, pero examina el encabezado enviado en su solicitud y busca el encabezado 'X-Requerido-Con: XmlHttpRequest' y si está presente, se examina el AjaxContext. Con el ayudante de acción AjaxContext puedes especificar qué contexto se debe usar para acciones específicas si la solicitud se activa con AJAX.

8

Puede utilizar las mismas acciones para devolver XML, JSON o lo que sea, mediante la detección de solicitudes ajax y así poder diferenciar las solicitudes ajax de las normales. Por ejemplo:

public function fooAction() 
{ 
    if($this->getRequest->isXmlHttpRequest()) { 
     echo json_encode($someData); 
    } else { 
     echo 'This is the normal output'; 
    } 
} 
+0

cómo elegir entre xml y json? ¿Debería formatear url like/posts/author/ivan para html, /posts/author/ivan.xml, /posts/author/ivan.json, /posts/author/ivan.rss etc. para formatos? –

+0

No, la URL sería la misma. Puede usar json_encode() para generar el contenido en formato JSON. http://ar2.php.net/json_encode –

+0

json es más liviano y más fácil de usar con IMO. Podría crear una vista JSON o podría hacer eco de json_encode() su matriz de datos sin usar una vista, probablemente tendría que desactivar la representación automática de la vista. – karim79

2

Su punto de vista puede ser algo distinto de HTML, y, o bien la tubería puede reaccionar a la petición de ser un puesto de Ajax, o su controlador puede reaccionar. De cualquier manera, debe ser tan simple como devolver una vista diferente.

1

Observe el AjaxContext Action-Helper (o el ContextSwitch uno, que se extiende), y le permitirá usar exactamente el mismo código de controlador, cambiando a un script de vista separado (foo.json. phtml, o foo.ajax.phtml, etc., recogidos automáticamente de un parámetro de formato?), o hacer uso de JSON Action-Helper que devolverá un objeto que comprende todas las variables que asigna a la vista, para que no lo haga necesita hacerse eco de su controlador (lo cual arruinará las pruebas unitarias, si las tiene).

+0

oh, claro. ¿Cómo no lo he visto? –

0

Mi sintaxis podría ser mayor, pero esto un boceto de mi acción RESTO de mi controlador Índice:

/** 
* REST Action for this application. 
* 
* @return void 
*/ 
public function restAction() 
{ 
    $this->_helper->viewRenderer->setNoRender(true); 

    $parameters = (func_num_args() > 0) ? array($key => func_get_arg(0)) : $this->getRequest()->getParams(); 

    $key = 'restCommand'; 
    if(!array_key_exists($key, $parameters)) throw new Exception('Request for “' . $key . '” not found.'); 
    $restCommand = $parameters[$key]; 

    $xmlString = IndexModel::getEmptyXmlSet($restCommand); 
    $xslFile = IndexModel::getModelFilePath('index'); 

    //Handle OPML-driven REST commands: 
    if(stripos($restCommand, 'opml-') === 0) 
    { 
     $opmlCall = explode('-', $restCommand); 
     if(count($opmlCall) != 3) 
     { 
      $xmlString = Songhay_SimpleXml::getXmlMessage('OPML Call Not Recognized', array('The number of parameters are incorrect.')); 
     } 
     else 
     { 
      $opmlSet = $opmlCall[1]; 
      $opmlId = $opmlCall[2]; 
      $xmlString = IndexModel::getRssFragmentWithOpml($opmlSet, $opmlId); 
     } 
    } 

    //Handle general REST commands: 
    switch($restCommand) 
    { 
     case 'deeplink': 
      $key = 'id'; 
      if(!array_key_exists($key, $parameters)) throw new Exception('Request for “' . $key . '” not found.'); 
      $url = $parameters[$key]; 
      $xmlString = IndexModel::getRssFragment($url); 
      $xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile); 
      break; 
     case 'index': 
      $opmlFile = IndexModel::getModelFilePath('index', '.xml'); 
      $xmlString = Songhay_SimpleXml::loadXmlAndStripNamespaces($opmlFile); 
      $xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile); 
      break; 
     default: 
      $xmlString = Songhay_SimpleXml::loadXslString($restCommand, $xmlString, $xslFile); 
    } 

    $response = $this->getResponse(); 
    $response->setHeader('Content-Type', 'text/xml'); 
    $response->setBody($xmlString); 

    return; 
} 
0

Cuando uso ajax con codeigniter, salgo directamente del controlador.

También uso un controlador independiente para solicitudes ajax simples como marcar, favoritos, etc. Para solicitudes ajax como inicio de sesión, contacto, etc., agregaría lógica a la ruta normal (por ejemplo, dominio.com/contacto). solicitud ajax Luego envío json y mato la ejecución del script.