Änderungen

Zur Navigation springen Zur Suche springen
1.969 Bytes hinzugefügt ,  01:13, 22. Mai 2020
K
→‎Die Web-Ebene: Angefangen Texte zu verbessern / Sachen hinzuzufügen etc. Aufgehört bei "Aktionen aneinander-reihen"
Jedes Skript erbt (unter anderem)
* von [https://docs.grails.org/3.3.9/ref/Command&#x20;Line/create-script.html GroovyScriptCommand], welches eine API für viele nützliche Aufgaben bereitstellt, sowie * von [https://docs.grails.org/3.3.9/api/org/grails/cli/profile/commands/templates/TemplateRenderer.html TemplateRenderer], welches die zur Code-Generierung genutzten <code>render</code>/<code>template</code>-Methoden zur Verfügung stellt. (Siehe Beispiel unten) 
</syntaxhighlight>
=== [https://docs.grails.org/3.3.9/guide/commandLine.html#_invoking_gradle Gradle-Tasks aufrufen] ===
Mithilfe der injezierten <code>gradle</code>-Variable können auch Gradle-Tasks getriggert werden:<syntaxhighlight lang="groovy">
gradle.compileGroovy()
</syntaxhighlight>
=== [https://docs.grails.org/3.3.9/guide/commandLine.html#_invoking_ant Ant-Tasks aufrufen] ===
Man kann auch Ant-Tasks aus Skripten heraus aufrufen, was beim schreiben von Codegenerierung und Automatisierungsaufgaben sehr nützlich sein kann:
</syntaxhighlight><br />
= [https://docs.grails.org/3.3.9/guide/commandLine.html#creatingCustomCommands Grails Befehle] =
== Unterschied Befehl und Skript ==
Im Gegensatz zu Skripten bewirken Befehle den Start der Grails-Umgebung, d.H. man hat den vollen Zugriff auf den Anwendungskontext und die Laufzeit.
=== Änderungen in Grails 3.2 ===
Seit Grails 3.2.0 haben Befehle ähnliche Fähigkeiten wie Skripte in Bezug auf das Abrufen von Argumenten, die Erzeugung von Vorlagen, den Dateizugriff und die Modellerstellung.
</syntaxhighlight><br />
== Befehle erstellen ==
Ähnlich wie bei Skripten kann man mit dem Befehl <code>$ grails create-command NAME</code> das Skelett eines Skriptes unter <code>src/main/commands/</code> erstellen lassen.
== Befehl ausführen ==
Selbst-geschriebene Befehle können
* mithilfe von <code>$ grails run-command NAME</code> oder* mithilfe des Gradle-Tasks "runCommand" <code>gradle runCommand -Pargs="NAME"</code> ** Wenn der Grails-Server ein Unterprojekt ist (z.B. in einem Projekt, das mit Angular erstellt wurde), kann der Unterprojekt-Befehl immer noch aus dem Gradle-Wrapper im übergeordneten Projekt aufgerufen werden: <code>./gradlew server:runCommand -Pargs="my-example"</code>
aufgerufen werden.
= [https://docs.grails.org/3.3.9/guide/commandLine.html#gradleBuild Gradle und Grails] =
TODO
=[https://docs.grails.org/3.3.109/guide/singletheWebLayer.html#theWebLayer Die Web-Ebene]=<br />==Controller==Ein [httphttps://docs.grails.org/latest3.3.9/guide/theWebLayer.html#controllers Controller] ==Ein Controller verarbeitet Anforderungen und erstellt oder bereitet die Antwort vor. Ein Controller kann die Antwort direkt generieren oder an eine Ansicht (View, <code>.gsp</code>) delegieren.
===Controller erstellen===
Mit dem Befehl Alle Controller befinden sich im Stammbaum unter <code>$ grails create-controller (PACKET.)KLASSEN-NAME app/controllers/APP_NAME</code> erstellt man das Skelett eines Controllers. Die einzige Voraussetzung für eine Klasse innerhalb dieser Hierarchie ist es, welches in mit <code>grails-app/controllers/APP-NAME/DEIN/PACKET/KLASSEN-NAMEController.groovy</code> gespeichert wirdzu enden. ''(Dieser Befehl ist nur zur vereinfachten Erstellung, man kann es auch manuell oder mit einer IDE machen)''
 Mit dem Befehl <code>$ grails create-controller (PAKET.)KLASSEN_NAME </code> erstellt man das Skelett eines Controllers, welches dann entsprechend unter <code>grails-app/controllers/APP_NAME/PAKET/KLASSEN_NAME.groovy</code> gespeichert wird.  * ''Dieser Befehl ist nur zur vereinfachten Generierung gedacht, man kann es auch manuell oder mit einer IDE machen.''  <br /> ===[https://docs.grails.org/3.3.9/guide/theWebLayer.html#_creating_actions Aktionen]===Die Standard [http://docs.grails.org/latest/guide/single.html#urlmappings URL-Mapping]-Konfiguration versichert , dass der Name des Controllers sowie jede Methode zum entsprechendem URI-Pfad gebunden wird.<br>Das folgende Beispiel ist hiermit unter <code>"...localhost:8080/mahlzeit/index" </code> erreichbar:
<syntaxhighlight lang="groovy">
package myapp
class MahlzeitController {
// Standard-Aktion
def index() { }
// Aktion "/list"
def list {
//..
// Controller-Logik
//..
return model
}
}
</syntaxhighlight>
Ein Controller kann mehrere öffentliche Methoden haben, welche sich (Wie oben beschrieben) jeweils zur einer URI binden.
====[https://docs.grails.org/3.3.9/guide/theWebLayer.html#_the_default_action Standard-Aktion]====Wenn der Nutzer keine bestimmte Aktion in seiner Anfrage stehen hat ''(Also zB. nur den Namen des Controllers, wie "<code>/mahlzeit/</code>" anstatt zB. "<code>/mahlzeit/login</code>") ''versucht Grails eine Standard-Aktion ausfindig zu machen, welche diese sich dieser Anfrage annimmtzur Verfügung stellt.
*Wenn es nur eine Aktion ''(aka. Methode)'' gibt, wird diese als Standard-Aktion anerkannt
Alternativ kann man auch eine eigenen Standard setzten, indem man <code>static defaultAction = "DEINE-METHODE"</code> in den Quellcode des Controllers einfügt.
<br />
==Scope-Variablen==
"Scope-Variablen" sind HashMap ähnliche Strukturen, in welche man Variablen speichern kann. Für Controller stehen folgende Scope-Variablen zur Verfügung:
===[http://docs.grails.org/latest/ref/Controllers/servletContext.html servletContext]: Statisch, für alle gleich===
Dieser Scope lässt uns Daten speichern, welche '''über die gesamte Web-App gleich statisch erreichbar sind(Applikationskontext).'''.<br>Das [http://docs.grails.org/latest/ref/Controllers/servletContext.html servletContext]-Objekt ist eine Instanz vom Standardmäßigen Java(EE)-Objekt [https://docs.oracle.com/javaee/7/api/javax/servlet/ServletContext.html ServletContext].
Es ist nützlich um:
===[http://docs.grails.org/latest/ref/Controllers/session.html session]: Für jede Sitzung anders===
Das [http://docs.grails.org/latest/ref/Controllers/session.html session]-Objekt ist eine Instanz von der Klasse [https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpSession.htmlHttpSession] der Java(EE) Servlet-API.
Es ist nützlich um '''Attribute der derzeitigen Sitzung eines Klientens zu speichern, wie zB. der Login (Name/Passwort).'''
===[http://docs.grails.org/latest/ref/Servlet%20API/request.html request]: Mitgesendete Informationen===
Das [http://docs.grails.org/latest/ref/Servlet%20API/request.html request]-Objekt ist eine Instanz von [https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html HttpServletRequest] der Java(EE) Servlet API.
Es ist nützlich um:
*Informationen des aktuellen Klienten zu erhalten
Grails fügt einige zusätzliche Funktionen zum [http://docs.grails.org/latest/ref/Servlet%20API/request.html request]-Objekt hinzu, ''die das standardmäßige [https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html HttpServletRequest]-Objekt nicht hat,'' hinzu:
*<code>XML</code> - Eine Instanz der [http://groovy.codehaus.org/api/groovy/util/slurpersupport/GPathResult.html GPathResult] welches erlaubt einkommende XML-Anfragen zu verarbeiten (Parsen) - Nützlich für REST
===([http://docs.grails.org/latest/ref/Controllers/params.html params]): (Veränderbare,) Mitgesendete CGI Informationen===
Eine veränderbare, mehrdimensionale HashMap von aller Anforderungsparametern (CGI).<br>Obwohl das [http://docs.grails.org/latest/ref/Servlet%20API/request.html request]-Objekt auch Methoden zum lesen der Anforderungsparametern enthältverfügt, ist diese der <code>params</code>-Scope manchmal nützlich für die [http://docs.grails.org/latest/guide/theWebLayer.html#dataBinding Daten-Bindung an Objekte].
Nehmen wir an wir haben folgende Anfrage: <code>hello?foo=bar</code>. In unserer Controll-Action "hello" können wir den Wert von <code>foo</code> nun ganz einfachausgeben lassenBeispiel:
<syntaxhighlight lang="groovy">
println def save() { def book = new Book(params.foo) // bind request parameters onto properties of book}
</syntaxhighlight>
===[http://docs.grails.org/latest/ref/Controllers/flash.html flash]: Speicher zwischen 2 Anfragen===
[[Datei:PostRedirectGet DoubleSubmitSolution.png|mini|Diagramm von Post/Redirect/Get. Quelle: [[commons:File:PostRedirectGet_DoubleSubmitSolution.png|Wikimedia]]]]Eine temporäre Speicherzuordnung, in der Objekte innerhalb der Sitzung für die nächste Anforderung , und auch nur für die nächste Anforderung , gespeichert werden. Die darin enthaltenen Objekte werden nach Abschluss der nächsten Anforderung automatisch gelöscht. Mit diesem Muster jk Sie HTTP-Weiterleitungen verwenden (Nützlich für [http://www.theserverside.com/tt/articles/article.tss?l=RedirectAfterPost Redirect after Post])und Werte beibehalten, die vom Flash-Objekt abgerufen werden können. Beispiel:<syntaxhighlight lang="groovy">class BookController {
Dies ist z.B. nützlich, um eine Nachricht direkt vor der Umleitung zu setzen: (Siehe [http://www.theserverside.com/tt/articles/article.tss?l=RedirectAfterPost Redirect after Post]-Konzept/Problemstellung)<syntaxhighlight lang="groovy">def delete() { def indexb = Book.get(params.id) if (!b) { flash.message = "Welcome!User not found for id ${params.id}" redirect(action: 'home'list)
}
... // remaining code
}
def homelist() {} // use "flash.message" in the rendered gsp-template or something like that
}
</syntaxhighlight>Bemerke: Die Namen und Typen die man dem <code>flash</code>-Objekt setzt können willkürlich sein.<br />==[https://docs.grails.org/3.3.9/guide/theWebLayer.html#_scoped_controllers Scope eines Controllers]==
Neu erstellte Controller haben den Standard-Scope-Wert "singleton". Verfügbare Controller-Scopes sind:
</syntaxhighlight>
Man kann den Scope eines Individuellen Controllers auch manuell ändern, indem man <code>static scope = "DEIN-SCOPE"</code> in den Quellcode des Controllers einfügt.
 
==[https://docs.grails.org/3.3.10/guide/single.html#modelsAndViews Model und Ansicht (Model and View)]==
Ein "Model" ist eine Map, die die Ansicht (View) beim Rendern verwendet.
*Die Schlüssel der Map korrespondieren mit dem Variablen-Namen über dessen sie von zBinnerhalb einer View (z.B. einer <code>.gsp</code>-Datei ) erreichbar sind.*Zu beachten ist, dass bestimmte Variablennamen im Modell nicht verwendet werden können:**<code>attributes</code>**<brcode>application</code>
 Es gibt einige Wege um ein Model zu übergeben/zu erzeugen:
*Explizit: Wenn seine Methode gleich wie die View-Datei heißt, übergibt man das Model einfach wie beim returnen mit folgendem Syntax: <code>[Var1: Data1, Var2: Data2, ...]</code>
</syntaxhighlight>
Eine erweiterte/bessere Weiße wäre es: *Springs Ein fortgeschrittenerer Ansatz ist die Rückgabe einer Instanz der Spring [https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/ModelAndView.html ModelAndView]-Klasse zu benutzen:
<syntaxhighlight lang="groovy">
import org.springframework.web.servlet.ModelAndView
}
</syntaxhighlight>
zu benutzen. Zu beachten ist, dass bestimmte Variablennamen in Ihrem Modell nicht verwendet werden können:<br />
*<code>attributes</code>*<code>application</code> ===Views View-Datei selber selektieren mit der render()-Methode===In den vorherhigen 2 Beispielen haben wir nirgendwo angegeben an welche [http://docs.grails.org/latest/guide/single.html#gsp viewView] die Map-Daten übergeben werden soll.<br>Dies liegt an Grails Konventionen. Im folgenden Beispiel würde Grails unter <code>grails-app/views/book/show.gsp</code> nachsuchen: ''(Nach dem Schema <code>grails-app/views/CONTROLLER/AKTION.gsp</code>)''
<syntaxhighlight lang="groovy">
class BookController {
''(Anmerkung: Wenn Grails keine <code>.gsp</code>-Datei finden kann, sucht es auch nach <code>.jsp</code>-Dateien.)''
<br />===Views für NamespacedSelektions-Controller selektierenVerfahren von Controllern die einem speziellen Namensraum angehören===Wenn ein Controller einen eigenen [http://docs.grails.org/latest/guide/single.html#namespacedControllers namespaceNamensraum] gesetzt hat (In diesem Beispiel '<code>business</code>'), schaut Grails
*zuerst nach ob die View-Datei unter <code>grails-app/views/business/...</code> zu finden ist
}
}
</syntaxhighlight><br />==[https://docs.grails.org/3.3.109/guide/singletheWebLayer.html#redirectsAndChaining RedirectsWeiterleitungen]==Aktionen können mithilfe der Controller-Methode <code>[http://docs.grails.org/latest/ref/Controllers/redirect.html redirect()]</code> umgeleitet werden.Beispiel:<syntaxhighlight lang="groovy">
class OverviewController {
}
</syntaxhighlight>
 
Auf welche Seite <code>[http://docs.grails.org/latest/ref/Controllers/redirect.html redirect()]</code> umleitet, kann man Grails auf mehrere Weisen mitteilen:
</syntaxhighlight>
* Domain-Klassen-Instanz: (Grails konstruiert einen Link unter Verwendung der Domänenklassen-ID, falls vorhanden.)<syntaxhighlight lang="groovy">// Redirect to the domain instanceBook book = ... // obtain a domain instanceredirect book</syntaxhighlight>   Parameter können von einer zu der anderen Aktion mithilfe des <code>params</code>-Arguments übergeben werden:.  Diese Daten befinden sich dann auch im <code>params</code>-Scope-Objekt der durch den Redirects resultierenden Anfrage der Aktion <code>myaction</code>.
<syntaxhighlight lang="groovy">
redirect(action: 'myaction', params: [myparam: "myvalue"])
</syntaxhighlight>
Diese werden dann in den Controller-Scope <codesyntaxhighlight lang="groovy">[httpredirect(action: 'myaction', params:params) //docs.grails.org/latest/ref/Controllers/Since both the "params.html "-Parameter and the "params]"-Controller-Scope are Map's, this is possible</codesyntaxhighlight> (Siehe oben) gespeichert. 
Mithilfe von <code>fragment</code> kann der Hash-Abteil der URL angegeben werden: (Im Standard URL-Mapping würde die folgende Methode in eine Weiterleitung auf <code>/myapp/test/show#profile</code> resultieren)<syntaxhighlight lang="groovy">
redirect(controller: "test", action: "show", fragment: "profile")
</syntaxhighlight><br />
===Aktionen aneinander-reihen===
<code>[http://docs.grails.org/3.1.1/ref/Controllers/chain.html chain()]</code> fungiert ähnlich wie <code>redirect()</code>,
chain(action: "action1", model: [one: 1], params: [myparam: "param1"])
</syntaxhighlight>
 
==Die [https://docs.grails.org/latest/ref/Controllers/render.html render()]-Methode==

Navigationsmenü