Package ch.tocco.nice2.web.core.api.clientquestion


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 Interface ch.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 Methode handleQuestion(question) implementieren). Der Parameter question ist das serialisierte Question-Objekt vom Server, von dem nun Informationen gelesen werden können. Sobald die Frage übers GUI beantwortet wurde, muss der Event clientAnswer 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 Methode ch.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.