Package ch.tocco.nice2.web.core.api.clientquestion
Ab V2.5 gibt es die Möglichkeit aus beliebigem Kontext, dem Benutzer Rückfragen zu stellen.
Ein klassische Beispiel:
- Der Status einer Veranstaltung wird auf "Abgesagt" gewechselt -> Frage an Benutzer, ob TN informiert werden sollen und Ressourcen freigegeben werden.
Aus dem Code Fragen stellen
Es gibt einige vorimplementierte Fragen, die ohne grossen Aufwand verwendet werden können. Die Fragetypen befinden
sich im Package ch.tocco.nice2.netui.clientquestion.impl
und sind jeweils im Code beschrieben, wozu sie
verwendet werden können. Zugehörig zur Fragen-Klasse gibt es jeweils auch eine Antwort-Klasse
Wenn nun irgendwo im Code eine Frage an den Benutzer erstellt werden soll, kann man sich an folgender Liste orientieren:
- Den
ClientQuestionService
injecten lassen. - Eine Frage aus dem obigen Package instanzieren und nach eigenem Bedürfnis konfigurieren. Dabei gilt es zu beachten, dass der ID-Parameter möglichst unique sein sollte, da mehrere Fragen pro Request möglich sind und da über die ID die vom Client kommende Antwort wieder mit der richtigen Frage verbunden wird.
YesNoClientQuestion question = new YesNoClientQuestion("mySuperFancyQuestionId", "clientquestion.mySuperFancyQuestion.header", "clientquestion.mySuperFancyQuestion.header");
- Dann kann mit dem
ClientQuestionService
die Frage gestellt werden:
ConfirmClientAnswer clientAnswer = clientQuestionService.askQuestion(question);
- Jetzt kann ich abhängig von der Antwort bestimmte Code-Blöcke ausführen:
if (clientAnswer.getAnswer()) { // do super fancy stuff } else { // don't super fancy stuff }
Ein eigenes Frage / Antwort - Paar entwickeln
Selbstverständlich können auch weitere Frage-Typen implementiert werden. Diese sollten natürlich möglichst generisch gehalten werden, damit sie an verschiedenen Orten verwendet werden können.
Vorgehen:
- Im Package
ch.tocco.nice2.netui.clientquestion.impl
eine Fragenklasse, d.h. das Interfacech.tocco.nice2.netui.clientquestion.ClientQuestion
implementieren. Dieses Fragen-Objekt wird dann an den Client geschickt und muss entsprechend DWR-konvertierbar sein (evtl. Converter registrieren). - Im selben Package eine Antwortklasse, d.h. das Interface
ch.tocco.nice2.netui.clientquestion.ClientAnswer
, implementieren. Dieses Antwort-Objekt muss auf dem Client (also in JS) erstellt werden können um dann an den Server geschickt zu werden. Die Antwortklasse kann nun als generischen Typ für die Fragenklasse gesetzt werden. - Jetzt kann der clientseitige Handler implementiert werden, am besten im Package
js.nice2.netui.clientquestion
im web-core Modul. Der Handler muss die Klasse/js/nice2/netui/clientquestion/AbstractClientQuestionHandler.js
erweitern (also die MethodehandleQuestion(question)
implementieren). Der Parameterquestion
ist das serialisierte Question-Objekt vom Server, von dem nun Informationen gelesen werden können. Sobald die Frage übers GUI beantwortet wurde, muss der EventclientAnswer
mit einem Antwort-Objekt (dasjenige, das wir auf dem Server für diese Frage erhalten) als Parameter geworfen werden. - Der Handler muss nun noch der Registry hinzugefügt werden:
nice2.netui.clientquestion.ClientQuestionHandlerRegistry.registerHandler("MyQuestionHandler", nice2.netui.clientquestion.MyClientQuestionHandler);
Die ID, auf die der Handler registriert wird, muss mit dem Wert, den die Methodech.tocco.nice2.netui.clientquestion.ClientQuestion#getClientHandlerName
zurückgibt.
Technische Info / Implementationsdetails
Folgender Ablauf beschreibt den "neuen" Program-Flow, wenn eine oder mehrere Rückfragen im Spiel sind:
- Beliebiger Request aus dem Client (z.B. Speichern der Veranstaltung nach Veränderung des Status)
- Request wird auf dem Server abgehandelt (z.B. starten einer Transaktion, anwerfen eines Listeners)
- Jetzt wird innerhalb des Request-Abhandelns eine Rückfrage gestellt (z.B. im Listener, der auf den Veranstaltungsstatus reagiert)
- Die Bearbeitung des Requests wird sofort abgebrochen und die Frage wird an den Client geschickt (z.B. die Frage ob bei den zugehörigen Anmeldungen ebenfalls ein Status gewechselt werden soll)
- Im Client wird der Fragenhandler angeworfen, der dem Benutzer einen Dialog o.ä. anzeigt um die Frage zu beantworten (z.B. ein Ja / Nein / Abbrechen Prompt)
- Der Benutzer beantwortet die Frage und der ursprüngliche Request wird erneut ausgeführt. Die Antwort zur Frage wird beim Request jetzt mitgeschickt.
- Request wird erneut auf dem Server abgehandelt (z.B. starten einer Transaktion, anwerfen eines Listeners)
- Jetzt wird innerhalb des Request-Abhandelns eine Rückfrage gestellt, aber jetzt ist eine Antwort vorhanden.
- Der Request läuft somit weiter und die Antwort wird auf irgendeine Weise verarbeitet.
Der Frage-Antwort Vorgang kann natürlich beliebig innerhalb eines Requests oft wiederholt werden. Es gilt dabei Folgendes zu beachten:
- Es wird wirklich der ganze Request erneut an den Server geschickt. Sollten Änderungen bereits committed worden sein, wenn eine Frage gestellt wird, werden dieselben Änderungen nach Beantwortung nochmals ausgeführt (was je nach Aktion zu ungewünschtem Verhalten führt).
- Ähnliches gilt natürlich für verschickte E-Mails usw.
-
ClassDescriptionAbstractClientQuestion<T extends ClientAnswer>Interface for an answer to a asynchronous question for the user.ClientQuestion<T extends ClientAnswer>Interface for a question to be asked the user.Modes for
PersistTasks
.Service to ask the client any questions at any point during code execution.A supplier for a default answer to a client questionDefines predefined answers for client questions.PredefinedAnswers.Answer<T extends ClientAnswer>