<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 16014 -->
<!-- Reviewed: no -->
<sect3 id="zend.controller.actionhelpers.contextswitch">
    <title>ContextSwitch und AjaxContext</title>

    <para>
        Der <emphasis>ContextSwitch</emphasis> Action Helfer ist vorgesehen für die Erleicherung
        bei der Rückgabe von unserschiedlichen Antwortformaten oder Anfragen. Der
        <emphasis>AjaxContext</emphasis> Helfer ist eine spezialisierte Version von
        <code>ContextSwitch</code> welche die Rückgabe von Antworten zu XmlHttpRequests
        erleichtert.
    </para>

    <para>
        Um einen von Ihnen zu aktivieren, muß der Controller darauf hingewiesen werden welche
        Aktion zu welchem Kontext antworten kann. Wenn eine hereinkommende Anfrage einen gültigen
        Kontext für eine gegebene Aktion indiziert, dann wird der Helfer:
    </para>

    <itemizedlist>
        <listitem><para>
                das Layout ausschalten wenn es eingeschaltet ist.
        </para></listitem>

        <listitem><para>
                einen alternativen View suffix setzen, was effektiv ein separates View Skript für
                den Kontext benötigt.
        </para></listitem>

        <listitem><para>
                die richtigen Antwort Header für den gewünschten Kontext senden.
        </para></listitem>

        <listitem><para>
                optional den spezifizierten Callback aufrufen um den Kontext zu definieren und/oder
                anschließende Berechnungen durchführen.
        </para></listitem>
    </itemizedlist>

    <para>
        Als Beispiel wird der folgende Controller angenommen:
    </para>

    <programlisting language="php"><![CDATA[
class NewsController extends Zend_Controller_Action
{
    /**
     * Landeseite; leitet zu listAction() weiter
     */
    public function indexAction()
    {
        $this->_forward('list');
    }

    /**
     * News Items auflisten
     */
    public function listAction()
    {
    }

    /**
     * Ein News Item anzeigen
     */
    public function viewAction()
    {
    }
}
]]></programlisting>

    <para>
        Angenommen wir wollen das <methodname>listAction()</methodname> auch im
        <acronym>XML</acronym> Format vorhanden ist. Statt der Erstellung einer anderen Aktion,
        kann angezeigt werden das eine <acronym>XML</acronym> Antwort zurückgegeben wird:
    </para>

    <programlisting language="php"><![CDATA[
class NewsController extends Zend_Controller_Action
{
    public function init()
    {
        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch->addActionContext('list', 'xml')
                      ->initContext();
    }

    // ...
}
]]></programlisting>

    <para>
        Was macht das:
    </para>

    <itemizedlist>
        <listitem><para>
                Setzt den 'Content-Type' Antwort Header auf '<filename>text/xml</filename>'.
        </para></listitem>

        <listitem><para>
                Ändert den View Suffix auf '<filename>xml.phtml</filename>' (oder, wenn ein
                alternativer View Suffix verwendet wird, 'xml.[dein Suffix]').
        </para></listitem>
    </itemizedlist>

    <para>
        Jetzt muß ein neues View Skript erstellt werden,
        '<filename>news/list.xml.phtml</filename>', welches das <acronym>XML</acronym> erzeugt und
        darstellt.
    </para>

    <para>
        Um zu ermitteln ob eine Anfrage eine Kontextänderung initiiert, prüft der Helfer auf ein
        token im Anfrage Objekt. Standardäßig schaut er auf den 'format' Parameter, durch den das
        konfiguriert werden kann. Das bedeutet das, in den meisten Fällen, um eine Kontextänderung
        zu triggern, ein 'format' Parameter in der Anfrage hinzugefügt werden kann:
    </para>

    <itemizedlist>
        <listitem><para>
                über <acronym>URL</acronym> Parameter: <filename>/news/list/format/xml</filename>
                (beachte, das Standard Routing Schema erlaubt übliche Schlüssel/Werte Paare nach
                der Aktion)
        </para></listitem>

        <listitem><para>
                über <acronym>GET</acronym> Parameter: z.B.,
                <filename>/news/list?format=xml</filename>
        </para></listitem>
    </itemizedlist>

    <para>
        <emphasis>ContextSwitch</emphasis> erlaubt es beliebige Kontexte zu spezifizieren,
        inklusive welche Kontextänderung stattfinden wird (wenn überhaupt), jegliche Antwort
        Header die gesendet werden sollen, und beliebige Callbacks für Initialisierung und folgende
        Bearbeitung.
    </para>

    <sect4 id="zend.controller.actionhelpers.contextswitch.contexts">
        <title>Vorhandene Standard Kontexte</title>

        <para>
            Standardmäßig sind zwei Kontexte im <emphasis>ContextSwitch</emphasis> Helfer
            vorhanden: json und xml.
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis><acronym>JSON</acronym></emphasis>. Der <acronym>JSON</acronym>
                    Kontext setzt den 'Content-Type' Antwort Header auf
                    '<filename>application/json</filename>' und den View Skript Suffix auf
                    '<filename>json.phtml</filename>'.
                </para>

                <para>
                    Trotzdem wird standardmäßig kein View Skript benötigt. Es serialisiert einfach
                    alle View Variablen und sendet die <acronym>JSON</acronym> Antwort sofort aus.
                </para>

                <para>
                    Dieses Verhalten kann deaktiviert werden indem die automatische
                    <acronym>JSON</acronym> Serialisierung abgeschaltet wird:
                </para>

                <programlisting language="php"><![CDATA[
$this->_helper->contextSwitch()->setAutoJsonSerialization(false);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <emphasis><acronym>XML</acronym></emphasis>. Der <acronym>XML</acronym> Kontext
                    setzt den 'Content-Type' Antwort Header auf '<filename>text/xml</filename>' und
                    den View Skript Suffix auf '<filename>xml.phtml</filename>'. Es muß ein neues
                    View Skript für den Kontext erstellt werden.
                </para>
            </listitem>
        </itemizedlist>
    </sect4>

    <sect4 id="zend.controller.actionhelpers.contextswitch.custom">
        <title>Eigene Kontexte erstellen</title>

        <para>
            Manchmal sind die Standardkontexte nicht genug. Zum Beispiel wenn man
            <acronym>YAML</acronym> zurückgeben will, oder <acronym>PHP</acronym> serialisieren,
            ein <acronym>RSS</acronym> oder <acronym>ATOM</acronym> Feed, usw.
            <emphasis>ContextSwitch</emphasis> erlaubt es das zu tun.
        </para>

        <para>
            Der einfachste Weg einen neuen Kontext hinzuzufügen ist über die
            <methodname>addContext()</methodname> Methode. Diese Methoe nimmt zwei Argumente, den
            Namen des Kontextes, und eine Array Spezifikation. Die Spezifikation sollte ein oder
            mehrere der folgenden Dinge enthalten:
        </para>

        <itemizedlist>
            <listitem>
                <para><emphasis>suffix</emphasis>: Der Suffix der dem Standard View Suffix angefügt
                werden soll der im ViewRenderer registriert ist.</para>
            </listitem>

            <listitem>
                <para><emphasis>headers</emphasis>: Ein Array von Header zu Wert Paaren das als Teil
                der Antwort gesendet werden soll.</para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>callbacks</emphasis>: Ein Array das ein oder mehrere der Schlüssel
                    'init' oder 'post' enthält, die auf gültige <acronym>PHP</acronym> Callbacks
                    zeigen und die für die Initialisierung des Contextes und die Nachbearbeitung
                    verwendet werden können.
                </para>

                <para>Initialisierungs Callbacks treten auf wenn der Kontext durch
                <emphasis>ContextSwitch</emphasis> erkannt wird. Sie können verwendet werden um
                spezielle Logik auszuführen die stattfinden soll. Als Beispiel verwendet der
                <acronym>JSON</acronym> Kontext einen Callback um den ViewRenderer auszuschalten
                wenn die automatische <acronym>JSON</acronym> Serialisierung eingeschaltet ist.
                </para>

                <para>Nachbearbeitung tritt wärend der <methodname>postDispatch()</methodname>
                Routine der Aktion auf, und kann verwendet werden um spezielle Logik auszuführen.
                Als Beispiel verwendet der <acronym>JSON</acronym> Kontext einen Callback um
                festzustellen ob die automatische <acronym>JSON</acronym> Serialisierung
                eingeschaltet ist; wenn dem so ist, serialisiert es die View Variablen zu
                <acronym>JSON</acronym> und sendet die Antwort, aber wenn dem nicht so ist,
                schaltet es den ViewRenderer wieder ein.</para>
            </listitem>
        </itemizedlist>

        <para>
            Es gibt eine Vielzahl an Methoden für die Interaktion mit Kontexten:
        </para>

        <itemizedlist>
            <listitem><para>
                <methodname>addContext($context, array $spec)</methodname>: Fügt einen neuen
                Kontext hinzu. Wirft eine Ausnahme wenn der Kontext bereits existiert.
            </para></listitem>

            <listitem><para>
                <methodname>setContext($context, array $spec)</methodname>: Fügt einen neuen
                Kontext hinzu oder überschreibt einen bestehenden Kontext. Verwendet die gleiche
                Spezifikation wie <methodname>addContext()</methodname>.
            </para></listitem>

            <listitem><para>
                <methodname>addContexts(array $contexts)</methodname>: Fügt viele Kontexte auf
                einmal hinzu. Das <varname>$contexts</varname> Array sollte ein Array von
                Kontext zu Spezifikation Paaren sein. Wenn einer der Kontexte bereits existiert,
                wird eine Ausnahme geworfen.
            </para></listitem>

            <listitem><para>
                <methodname>setContexts(array $contexts)</methodname>: Fügt neue Kontexte hinzu und
                überschreibt bestehende. Verwendet die gleiche Spezifikation wie
                <methodname>addContexts()</methodname>.
            </para></listitem>

            <listitem><para>
                <methodname>hasContext($context)</methodname>: Gibt true zurück wenn der Kontext
                existiert, andernfalls false.
            </para></listitem>

            <listitem><para>
                <methodname>getContext($context)</methodname>: Empfängt einen einzelnen Kontext
                durch den Namen. Gibt ein Array zurück das der Spezifikation folgt die in
                <methodname>addContext()</methodname> verwendet wird.
            </para></listitem>

            <listitem><para>
                <methodname>getContexts()</methodname>: Empfängt alle Kontexte. Gibt ein Array von
                Kontext zu Spezifikation Paaren zurück.
            </para></listitem>

            <listitem><para>
                <methodname>removeContext($context)</methodname>: Entfernt einen einzelnen Kontext
                durch seinen Namen. Gibt im Erfolgsfall true zurück, und false wenn der Kontext
                nicht gefunden wurde.
            </para></listitem>

            <listitem><para>
                <methodname>clearContexts()</methodname>: Entfernt alle Kontexte.
            </para></listitem>
        </itemizedlist>
    </sect4>

    <sect4 id="zend.controller.actionhelpers.contextswitch.actions">
        <title>Kontexte per Aktion setzen</title>

        <para>
            Es gibt zwei Mechanismen für das Setzen vorhandener Kontexte. Es kann entweder manuell
            ein Array im Controller erstellt werden, oder es können verschiedene Methoden in
            <emphasis>ContextSwitch</emphasis> verwendet werden um Sie zu bauen.
        </para>

        <para>
            Die prinzipielle Methode für das Hinzufügen von Aktion zu Kontext Relationen ist
            <methodname>addActionContext()</methodname>. Sie erwartet zwei Argumente, die Aktion zu
            welcher der Kontext hinzugefügt werden soll, und entweder den Namen des Kontextes oder
            ein Array von Kontexten. Als Beispiel nehmen wir die folgende Controller Klasse an:
        </para>

        <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function listAction()
    {
    }

    public function viewAction()
    {
    }

    public function commentsAction()
    {
    }

    public function updateAction()
    {
    }
}
]]></programlisting>

        <para>
            Angenommen wir sollen einen <acronym>XML</acronym> Kontext zu der 'list' Aktion
            hinzufügen, und <acronym>XML</acronym> und <acronym>JSON</acronym> Kontexte zu der
            'comments' Aktion. Wir können das in der <methodname>init()</methodname> Methode
            machen:
        </para>

        <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->contextSwitch()
             ->addActionContext('list', 'xml')
             ->addActionContext('comments', array('xml', 'json'))
             ->initContext();
    }
}
]]></programlisting>

        <para>
            Alternativ kann einfach die Array-Eigenschaft <varname>$contexts</varname> definiert
            werden:
        </para>

        <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public $contexts = array(
        'list'     => array('xml'),
        'comments' => array('xml', 'json')
    );

    public function init()
    {
        $this->_helper->contextSwitch()->initContext();
    }
}
]]></programlisting>

        <para>
            Das obige ist weniger Overhead, aber enthält auch potentielle Fehler.
        </para>

        <para>
            Die folgenden Methoden können verwendet werden um die Kontext-Mappings zu erstellen:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>addActionContext($action, $context)</methodname>: markiert einen
                    oder mehrere Kontexte als in einer Aktion vorhanden. Wenn bereits Mapping
                    existieren wird einfach bei diesen Mappings angehängt.
                    <varname>$context</varname> kann ein einzelner Kontext sein, oder ein Array von
                    Kontexten.
                </para>

                <para>
                    Ein Wert von <constant>TRUE</constant> für den Kontext markiert alle vorhandenen
                    Kontexte als vorhanden für die Aktion.
                </para>

                <para>
                    Ein leerer Wert für <varname>$context</varname> deaktiviert alle Kontexte für
                    die gegebene Aktion.
                </para>
            </listitem>

            <listitem><para>
                    <methodname>setActionContext($action, $context)</methodname>: markiert einen
                    oder mehrere Kontexte als in einer Aktion vorhanden. Wenn bereits Mappings
                    existieren werden Sie mit den spezifizierten ersetzt.
                    <varname>$context</varname> kann ein einzelner Kontext sein, oder ein Array von
                    Kontexten.
            </para></listitem>

            <listitem><para>
                    <methodname>addActionContexts(array $contexts)</methodname>: fügt mehrere
                    Aktion zu Kontext Paare auf einmal hinzu. <varname>$contexts</varname> sollte
                    ein assoziatives Array von Aktion zu Kontext Paaren sein. Es entspricht
                    <methodname>addActionContext()</methodname>, was bedeutet das wenn eine Paarung
                    bereits existiert, diese hinzugefügt wird.
            </para></listitem>

            <listitem><para>
                    <methodname>setActionContexts(array $contexts)</methodname>: fungiert wie
                    <methodname>addActionContexts()</methodname>, überschreibt aber bestehende
                    Aktion zu Kontext Paare.
            </para></listitem>

            <listitem><para>
                    <methodname>hasActionContext($action, $context)</methodname>: ermittelt ob eine
                    spezielle Aktion einen gegebenen Kontext hat.
            </para></listitem>

            <listitem><para>
                    <methodname>getActionContexts($action = null)</methodname>: gibt entweder alle
                    Kontexte für eine gegebene Aktion zurück, oder alle Aktion zu Kontext Paare.
            </para></listitem>

            <listitem><para>
                    <methodname>removeActionContext($action, $context)</methodname>: entfernt ein
                    oder mehrere Kontexte von einer gegebenen Aktion. <varname>$context</varname>
                    kann ein einzelner Kontext sein, oder ein Array von Kontexten.
            </para></listitem>

            <listitem><para>
                    <methodname>clearActionContexts($action = null)</methodname>: entfernt alle
                    Kontexte von einer gegebenen Aktion, oder von allen Aktionen mit Kontexten.
            </para></listitem>
        </itemizedlist>
    </sect4>

    <sect4 id="zend.controller.actionhelpers.contextswitch.initcontext">
        <title>Kontext Switching initialisieren</title>

        <para>
            Um Kontext Switching zu initialisieren, muß <methodname>initContext()</methodname> im
            Action Controller aufgerufen werden:
        </para>

        <programlisting language="php"><![CDATA[
class NewsController extends Zend_Controller_Action
{
    public function init()
    {
        $this->_helper->contextSwitch()->initContext();
    }
}
]]></programlisting>

        <para>
            In einigen Fällen, will man einen Kontext erzwingen der verwendet werden soll; zum
            Beispiel wenn man nur den <acronym>XML</acronym> Kontext erlauben will wenn Kontext
            Switching aktiviert ist. Das kann durch die Übergaben des Kontextes zu
            <methodname>initContext()</methodname> getan werden:
        </para>

        <programlisting language="php"><![CDATA[
$contextSwitch->initContext('xml');
]]></programlisting>
    </sect4>

    <sect4 id="zend.controller.actionhelpers.contextswitch.misc">
        <title>Zusätzliche Funktionalitäten</title>

        <para>
            Eine Vielzahl an Methoden kann verwendet werden um das Verhalten des
            <emphasis>ContextSwitch</emphasis> Helfers zu verändern. Diese sind:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>setAutoJsonSerialization($flag)</methodname>: Standardmäßig
                    serialisieren <acronym>JSON</acronym> Kontexte alle View Variablen in die
                    <acronym>JSON</acronym> Notierung und geben diese als Antwort zurück. Wenn man
                    seine eigene Antwort erstellen will, sollte das ausgeschaltet werden; das muß
                    vor dem Aufruf von <methodname>initContext()</methodname> geschehen.
                </para>

                <programlisting language="php"><![CDATA[
$contextSwitch->setAutoJsonSerialization(false);
$contextSwitch->initContext();
]]></programlisting>

                <para>
                    Der Wert des Flags erhält man mit
                    <methodname>getAutoJsonSerialization()</methodname>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setSuffix($context, $suffix,
                        $prependViewRendererSuffix)</methodname>: Mit
                    dieser Methode kann ein anderer Suffix spezifiziert werden der für einen
                    gegebenen Kontext verwendet werden soll. Das dritte Argument wird verwendet um
                    anzuzeigen ob der aktuelle Suffix des ViewRenderers dem neuen Suffix
                    vorangestellt werden soll oder nicht; dieses Flag ist standardmäßig aktiviert.
                </para>

                <para>
                    Die Übergabe eines leeren Werte an den Suffix führt dazu das nur der Suffix des
                    ViewRenderers verwendet wird.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addHeader($context, $header, $content)</methodname>: Fügt einen
                    Antwort Header für einen gegebenen Kontext hinzu. <varname>$header</varname>
                    ist der Headername, und <varname>$content</varname> ist der Wert der an diesen
                    Header übergeben werden soll.
                </para>

                <para>
                    Jeder Kontxt kann mehrere Header haben; <methodname>addHeader()</methodname>
                    fügt zusätzliche Header in den Header Stack des Kontextes ein.
                </para>

                <para>
                    Wenn der spezifizierte <varname>$header</varname> bereits für diesen Kontext
                    existiert, wird eine Ausnahme geworfen.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setHeader($context, $header, $content)</methodname>:
                    <methodname>setHeader()</methodname> funktioniert wie
                    <methodname>addHeader()</methodname>, ausser das sie erlaubt das
                    existierende Kontext Header überschrieben werden.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>addHeaders($context, array $headers)</methodname>: Fügt einen
                    gegebenen Kontext mehrere Header auf einmal hinzu. Entspricht
                    <methodname>addHeader()</methodname>, was bedeutet das eine Ausnahme geworfen
                    wird wenn der Header bereits existiert. <varname>$headers</varname> ist ein
                    Array von Header zu Kontext Paaren.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setHeaders($context, array $headers.)</methodname>: Wie
                    <methodname>addHeaders()</methodname>, nur das es
                    <methodname>setHeader()</methodname> entspricht und damit das Überschreiben
                    existierender Header erlaubt.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getHeader($context, $header)</methodname>: Enpfängt den Wert eines
                    Headers für einen gegebenen Kontext. Gibt null zurück wenn dieser nicht
                    gefunden wird.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>removeHeader($context, $header)</methodname>: Entfernt einen
                    einzelnen Header für einen gegebenen Kontext.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>clearHeaders($context, $header)</methodname>: Entfernt alle Header
                    für einen gegebenen Kontext.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setCallback($context, $trigger, $callback)</methodname>: Setzt
                    einen Callback bei einem gegebenen Trigger für einen gegebenen Kontext. Trigger
                    können entweder 'init' oder 'post' sein (was zeigt das der Callback entweder
                    bei der Initialisierung oder der Nachbearbeitung aufgerufen wird).
                    <varname>$callback</varname> sollte ein gültiger <acronym>PHP</acronym>
                    Callback sein.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setCallbacks($context, array $callbacks)</methodname>: Setzt
                    mehrere Callbacks für einen gegebenen Kontext. <varname>$callbacks</varname>
                    sollte ein Trigger zu Callback Paar sein. Aktuell sind die meisten Callbacks
                    die registriert werden können zwei, einer für Initialisierung und einer für die
                    Nachbearbeitung.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getCallback($context, $trigger)</methodname>: Empfängt einen
                    Callback für einen gegebenen Trigger in einem gegebenen Kontext.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getCallbacks($context)</methodname>: Empfängt alle Callbacks für
                    einen gegebenen Kontext. Gibt ein Array von Trigger zu Callback Paaren zurück.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>removeCallback($context, $trigger)</methodname>: Entfernt einen
                    Callback für einen gegebenen Trigger und Kontext.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>clearCallbacks($context)</methodname>: Entfernt alle Callbacks für
                    einen gegebenen Kontext.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setContextParam($name)</methodname>: Setzt den Anfrageparameter der
                    geprüft werden muß um zu entscheiden ob eine Kontextumschaltung angefragt wurde
                    oder nicht. Der Wert ist standardmäßig 'format', aber dieser Zugriffspunkt kann
                    verwendet werden um einen alternativen wert zu setzen.
                </para>

                <para>
                    <methodname>getContextParam()</methodname> kann verwendet werden um den
                    aktuellen Wert zu erhalten.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>setAutoDisableLayout($flag)</methodname>: Standardmäßig sind
                    Layouts ausgeschaltet wenn eine Kontextumschaltung erfolgt; das ist weil
                    Layouts typischerweise dafür verwendet werden um normale Antworten
                    darzustellen, und Sie in alternativen Kontexten keine Bedeutung haben. Wenn man
                    trotzdem Layouts verwenden will (möglicherweise hat man ein Layout für einen
                    neuen Kontext), kann dieses Verhalten mit der Übergabe eines false Wertes an
                    <methodname>setAutoDisableLayout()</methodname> geändert werden. Das sollte
                    aber <emphasis>before</emphasis> dem Aufruf von
                    <methodname>initContext()</methodname> geschehen.
                </para>

                <para>
                    Um den Wert dieses Flags zu erhalten, kann der Zugriffspunkt
                    <methodname>getAutoDisableLayout()</methodname> verwendet werden.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>getCurrentContext()</methodname> kann verwendet werden um
                    festzustellen welcher Kontext erkannt wurde, wenn überhaupt. Er gibt null
                    zurück wenn keine Kontextumschaltung stattgefunden hat, oder wenn er aufgerufen
                    wurde bevor <methodname>initContext()</methodname> stattgefunden hat.
                </para>
            </listitem>
        </itemizedlist>
    </sect4>

    <sect4 id="zend.controller.actionhelpers.contextswitch.ajaxcontext">
        <title>AjaxContext Funktionalität</title>

        <para>
            Der <emphasis>AjaxContext</emphasis> Helfer erweitert
            <emphasis>ContextSwitch</emphasis>, sodas alle für <emphasis>ContextSwitch</emphasis>
            gelisteten Funktionalitäten in Ihm vorhanden sind. Es gibt trotzdem ein paar wichtige
            Änderungen.
        </para>

        <para>
            Zuerst, verwendet es eine andere Action Controller Eigenschaft
            <varname>$ajaxable</varname> um Kontexte festzustellen. Damit kann man verschiedene
            Kontexte verwenden für <acronym>AJAX</acronym> gegenüber normalen
            <acronym>HTTP</acronym> Anfragen. Die verschiedenen
            *<methodname>ActionContext()</methodname>* Methoden von
            <emphasis>AjaxContext</emphasis> schreiben in diese Eigenschaft.
        </para>

        <para>
            Zweitens, wird nur dann getriggert wenn ein XmlHttpRequest stattgefunden hat, was durch
            die <methodname>isXmlHttpRequest()</methodname> Methode den Anfrageobjektes
            festgestellt wird. Deshalb wird, wenn der Kontextparameter ('format') in der Anfrage
            übergeben wird, aber die anfrage nicht als XmlHttpRequest gemacht wurde, keine
            Kontextumschaltung getriggert.
        </para>

        <para>
            Drittens, fügt der <emphasis>AjaxContext</emphasis> einen zusätzlichen,
            <acronym>HTML</acronym>, Kontext hinzu. In diesem Kontext setzt er den Suffix auf
            '<filename>ajax.phtml</filename>' um diesen Kontext von einer normalen Anfrage zu
            unterscheiden. Es werden keine zusätzlichen Header zurückgegeben.
        </para>

        <example id="zend.controller.actionhelpers.contextswitch.ajaxcontext.example">
            <title>Aktionen erlauben auf Ajax Anfragen zu antworten</title>

            <para>
                In dem folgenden Beispiel erlauben wir Anfragen auf die Aktionen 'view', 'form' und
                'process' auf <acronym>AJAX</acronym> Anfragen zu antworten. In den ersten zwei
                Fällen, 'view' und 'form' wird ein <acronym>HTML</acronym> Teilstück zurückgegeben
                mit dem die Seite aktualisiert werden soll; im letzteren wird
                <acronym>JSON</acronym> zurückgegeben.
            </para>

            <programlisting language="php"><![CDATA[
class CommentController extends Zend_Controller_Action
{
    public function init()
    {
        $ajaxContext = $this->_helper->getHelper('AjaxContext');
        $ajaxContext->addActionContext('view', 'html')
                    ->addActionContext('form', 'html')
                    ->addActionContext('process', 'json')
                    ->initContext();
    }

    public function viewAction()
    {
        // Ein einzelnes Kommentar holen um es anzuzeigen.
        // Wenn AjaxContext erkannt wurde, verwendet es das
        // comment/view.ajax.phtml View Skript.
    }

    public function formAction()
    {
        // Stellt die "add new comment" Form dar.
        // Wenn AjaxContext erkannt wurde, verwendes es das
        // comment/form.ajax.phtml View Skript.
    }

    public function processAction()
    {
        // Bearbeitet einen neuen Kommentar
        // Gibt das Ergebnis als JSON zurück; fügt die Ergebnisse einfach als
        // View Variablen hinzu, und JSON wird zurückgegeben.
    }
}
]]></programlisting>

            <para>
                Auf der Seite des Clients, wird die <acronym>AJAX</acronym> Bibliothek einfach die
                Endpunkte '<filename>/comment/view</filename>',
                '<filename>/comment/form</filename>', und '<filename>/comment/process</filename>'
                anfragen, und den 'format' Parameter übergeben:
                '<filename>/comment/view/format/html</filename>',
                '<filename>/comment/form/format/html</filename>',
                '<filename>/comment/process/format/json</filename>'. (Oder der Parameter
                kann über den Abfrage String übergeben werden: z.B. , "?format=json".)
            </para>

            <para>
                Angenommen die Bibliothek übergibt den 'X-Requested-With: XmlHttpRequest'
                Header, dann werden diese Aktionen das richtige Antwortformat zurückgeben.
            </para>
        </example>
    </sect4>
</sect3>
<!--
vim:se ts=4 sw=4 et:
-->
