Facebook
Twitter
Google+
Kommentare
18

Zend Framework + AJAX

Ich werde euch heute mal anhand eines kleinen Beispiels zeigen, wie man das Zend Framework und AJAX schnell und einfach verbinden kann. Ich habe dazu das ZF in der Version 1.7 und das Javascript Framework jQuery in der Version 1.3.2 verwendet.Ich gehe einmal davon aus das Grundkenntnisse im ZF vorhanden sind, falls nicht gibt es schon genügend Tutorials im Internet und eine sehr gelungene Doku von Zend selbst. Da jQuery alles andere als kompliziert ist, aber dabei trotzdem wirklich viele Möglichkeiten bietet, werde ich kurz einige Basisfunktionen und die Handhabung erklären, der Rest kann ebenfalls in der übersichtlichen und einfachen Doku nachgelesen werden.

ZF

Okay, kommen wir einmal zum ZF. In meinem Beispiel werde ich zwei Controller verwenden. Der erste dient zur Darstellung einer div-box und der zweite gibt einen kleinen Text aus. Nichts besonderes eigentlich. Ich gehe einfach mal davon aus das bereits ein Projektverzeichnis mit dem ZF eingerichtet und eine bootstrapper Datei erstellt wurde.
Der erste Controller ist der Controller show. Hier finden wir eine leere showAction die selbst nichts tut, sondern lediglich den view öffnet. In dem View befindet sich dann der Grundaufbau einer HTML Seite.

showController.php

<?php

class showController extends Zend_Controller_Action
{
  function showAction()
  {
    // Ruft automatisch den View "show" auf
  }
}

show.phtml

<html>
  <head>
    <title>Beispiel</title>
  </head>
  <body>
    <div id="textBox"></div>
  </body>
</html>

Der zweite Controller gibt lediglich einen Text aus. Ich nenne ihn einfach mal „output“. Das ganze werde ich ohne eine View erledigen, dass ist für einen kleinen Einzeiler einfacher.

outputController.php

<?php
class outputController extends Zend_Controller_Action
{
  function outputAction()
  {
    $this->_helper-> viewRenderer-> setNoRender();
    echo "Das ist meine Ausgabe!";
  }
}

Das ist auch schon alles was ich vom ZF benötige. Wir werde später noch Änderungen in der View der showAction machen, damit wir jQuery laden und den Text laden können.

jQuery

jQuery ist meiner Meinung nach ein wirklich erstaunliches Framework. Ich habe vom allgemeinen Funktionsumfang noch keinen direkten Vergleich mit Scriptaculous bzw. Prototype oder MooTools gemacht, aber ich vermute mal das jQuery im allgemeinen eher weniger Funktionen enthält. Was aber wirklich toll an dem Framework ist, ist der Zugriff auf die HTML Elemente. So kann man mithilfe von jQuery so ziemlich jeden CSS Ausdruck zum auswählen eines oder mehrerer Elemente nutzen um Eigenschaften zuzuweisen o.Ä. So ist z.B. eine Abfrage aller input Felder vom Typ Text so möglich:

var elem = $("input ['type=text']");

So wird das lästige „document.getElementBy…“ ersetzt und extrem vereinfacht. Ein weiterer Punkt, und den werden wir jetzt auch nutzen, ist die Vereinfachung eines „AJAX Requests“. jQuery bietet dabei verschiedenste Möglichkeiten. Ich werde heute einmal $.post verwenden. Hier dazu die komplette Funktion die benötigt wird um ein AJAX Request abzufeuern und das Ergebnis – den Text – in die div zu schreiben:

function getText()
{
  $.post("output/output",
  function(response) {
    $("#textBox").text(response);
  },
  "text"
  );
}

Diese Funktion muss nun nur noch über ein Link aufgerufen werden. Mitsamt der Einbindung der Funktion, der jQuery Datei und des Links sieht die show View dann so aus:

show.phtml

<html>
<head>
  <title>Beispiel</title>
  <script src="jQuery.js" type="text/javascript" />
  <script type="text/javascript">
    function getText()
    {
      $.post("output/output",
           function(response) {
      $("#textBox").text(response);
    },
    "text"
    );
  }
  </script>
</head>
<body>
  <div id="textBox"></div><br />
  <a onclick="getText();">loadText</a>
</body>
</html>

So, das wars dann auch schon. Auf diesem Wege kann man dann auch über das ZF Daten aus einer Datenbank abrufen, Daten speichern oder in jeglicher Art weiterverarbeiten. Ich hoffe das ich das ganze relativ verständlich erklärt habe und freue mich über eure Kommentare

Über den Autor

Sven Finke

Kommentare

18 Comments

  1. „echo“ im Controller – wer macht denn soetwas?!
    Alter „onclick“-Mist? Das geht aber mit jQuery viel besser: (z.B.)

    HTML: loadText
    JS: $(‚loadButton‘).click(function() { getText(); });

    Mische NIEMALS JavaScript und HTML!!!

    Reply
  2. Da stimme ich Walter S. zu. Zum Controller seh ich es ja des Beispiels wegen noch ein, solange man noch einen Hinweis darauf gibt. Den JS Anteil sollte man allerdings gleich im Beispiel trennen, so wie bsp.weise W.S. gesagt hat.

    Reply
  3. @Tobias: Leider habe ich keine Ahnung was ein JSON Helper ist 🙂 Der Artikel ist ja auch gar nicht von mir, deswegen halte ich mich da auch mal raus. Getreu nach dem Motto: „Wer keine Ahnung hat, sollte einfach mal die Klappe halten.“ 🙂 Passt in dem Punkt ganz gut auf mich zu.

    Reply
  4. Zum setzen der $.POST url würd ich den URL-Helper des ZF nehmen. OutputController schreibt man groß.

    Ans Volk:
    Schalte ich mit setNoRender auch autom. das Layout aus?

    Reply
  5. Finde ein echo im Controller jetzt nicht so wild. Wozu noch umständlich ein template laden wenn man im endeffekt sowieso z.B. nur eine json ausgabe will…

    echo json_encode($meine_date) und gut ist. da noch extra ein template nutzen ist einfach nur sinnlose ressourcenverschwendung…

    Reply
  6. @Bartek: Was echo im Controller angeht, da hast du das Problem, dass du diesen Controller nicht für andere Zwecke verwenden kannst (etwas z.B. zu dekorieren, dass einen Output hat, ist wirklich kein Spass). Und ausserdem verletzt du damit eine der wichtigsten Grundregeln: Trennung zwischen View und Controller. Ich tippe mal drauf, dass sich jedes „echo“ einmal rächen wird.

    Reply
  7. Ok, da hast du durchaus recht. An den Fall habe ich jetzt garnicht gedacht. Ich dekoriere aber auch so selten mal einen Controller…

    Reply
  8. Okay, da kam jetz ja einiges an Kritik^^

    Erstmal zu dem Javascript:

    Da es nur ein kleines Beispiel sein sollte wollte ich die eine Javascript Funktion nicht extra in eine neue Datei auslagern. In der späteren Anwendung sollte man das natürlich machen.

    Zu dem echo:

    Ich hätte das ganze natürlich in ein View auslagern können bzw. sollen. Aber für einen kleinen Satz wollte ich nicht extra eine neue View anlegen. Aber ihr habt vollkommen recht, Ausgaben in einem Controller zu machen ist nicht gerade die feine englische Art…

    Trotzdem erstmal Danke für die Kommentare!

    Gruß, Sven

    Reply
  9. Hallo,

    es gab ja schon einige Verbesserungsvorschläge zu deinem Artikel. Ich möchte noch einige Punkte hinzufügen:

    1. Würde ich nicht extra einen zweiten Controller, nur für die Ajax aufrufe erstellen. Du läufst so zu sehr gefahr, dass du die Actions aus mehrern Controller, schlimmer noch, aus mehreren Modulen wiederverwendest. Wiederverwendbarkeit ist doch nichts schlechtes, stimmts? Richtig, aber an der falschen Stelle eingesetzt schon. Statt dessen lege ich die Ajax Actions direkt dort ab wo sie auch gebraucht werden; im aktuelle Controller.

    2. Verwendung des Context Switch Helpers. (siehe http://framework.zend.com/manual/de/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch.ajaxcontext)

    3. Verwendung einer View. Das wurde schon mehrfach gesagt, macht aber mit dem Action Helper gleich sichtbar sinn. Die Views werden nämlich unterschiedlich benannt. z.B. show.ajax.phtml oder show.json.phtml. In der Methode showAction rufst du das Model auf welches dir die gewünschten Daten zur Ausgabe besorgt, der Controller reicht dies weiter an die View (die ja, je nach Context unterschiedlich ist) und erst dort geschieht die Aufbereitung zur Darstellung im entsprechenden Format. z.B. die Konvertierung in das JSON Format.

    Nicht entmutigen lassen und gleich Korrekturen nachreichen. Nur so wird man besser.

    Grüße,
    Thorsten

    Reply
  10. Um AJAX auszugeben ist folgendes m.E. am einfachsten:

    public function newsAction()
    {
    $this->_helper->contextSwitch()->initContext(‚json‘);
    $this->view->news = array(‚today‘ => ’nothing new‘);
    }

    Ein Viewscript wird nicht mehr benötigt – der contextSwitch ActionHelper gibt einfach alles in $this->view als JSON aus.

    Alexander

    Reply
  11. Ich finde es tatsächlich entgegen allen Dogmen übersichtlicher Event-Handler an die HTML-Elemente zu packen. Wenn man so ordentlich gecodet hat, dass dort nur ein Funktionsaufruf steht, finde ich das absolut in Ordnung.

    Dieses Verfahren hat auch einen gewichtigen Vorteil: Es kann nicht vorkommen dass man „versehentlich“ Elemente mit einem Klassennamen an ein Event bindet, weil ein Designer nichts von der Sonderbedeutung dieses Namens wusste.

    Reply

Leave a Comment.

Link erfolgreich vorgeschlagen.

Vielen Dank, dass du einen Link vorgeschlagen hast. Wir werden ihn sobald wie möglich prüfen. Schließen