
JavaScript Remoting in Visualforce: Ein Code-Beispiel

JavaScript Remoting ist eine Möglichkeit von einer Visualforce-Seite aus Datenbankaufrufe auszuführen und zu verarbeiten.
In seiner Funktionalität ist es den Visualforce-Konstrukten <apex:form> und <apex:actionFunction> ähnlich, unterscheidet sich in der Handhabung jedoch stark von diesen. Wieso sollte ich mich also mit JavaScript Remoting beschäftigen?
Wieso JavaScript Remoting?
In meinem aktuellen Kundenprojekt beschäftige ich mich zurzeit mit der Weiterentwicklung von Visualforce-Seiten. Der Kunde ist sich noch nicht sicher, ab wann es sich für ihn lohnt, von Salesforce Classic auf Lightning zu wechseln und eine Hindernis für den Wechsel stellen seine alten Visualforce Seiten dar. Die Seiten bestehen aus klassischen Konstrukten, wie <apex:inputField>, <apex:form> oder <apex:actionFunction> und besitzen damit Look-and-Feel der Salesforce Classic Seiten. Betrachte ich diese Seiten jedoch in der aktuellen Lightning Version von Salesforce, so haben diese weiterhin Salesforce Classic Optik oder verkommen gar zu einfachen Textseiten. Salesforce liefert hierfür zwar regelmäßig Updates, doch ist das Ganze noch nicht wirklich rund.
Lightning Design System
Als Entwickler habe ich mich daher entschieden, die Visualforce-Seiten meines Kunden durch Standard HTML Konstrukte zu ersetzen und mit JavaScript Funktionen zu erweitern. Salesforce bietet hierfür kostenfrei das Lightning Design System (Link) an, mit welchem Visualforce-Seiten mit Standard HTML Elementen wie Lightning Standard Seiten aussehen. Der im Vergleich zur alten Visualforce Seite gestiegene Entwicklungsaufwand wird hierbei durch höhere Flexibilität und einen größeren Grad der Anpassung ausgeglichen. Visualforce-Seiten können tatsächlich aussehen wie moderne Webseiten! Aber können Sie sich auch so verhalten?
Problemstellung
Was mich anfangs immer wieder vor Probleme und lästige Bugs gestellt hat, waren die Datenbankaufrufe über den Controller. Hier mal ein Beispiel: Ich benötige eine Funktion, mit der ich die Opportunities massenhaft absagen möchte. Ich habe eine Tabelle mit einer Reihe von Opportunities und möchte diese per Checkbox markieren und danach über einen Buttonclick auf den Status “Closed Lost” setzen. Hierzu habe ich eine Funktion im Controller, die eine Liste von Ids und einen neuen Status entgegennimmt.
Bediene ich mich der <apex>-Konstrukte so müsste ich als erstes eine <apex:actionFunction> definieren, die diese Funktion im Controller aufruft und zusätzlich noch zwei <apex:param> hinzufügen, die die eingetragenen Werte an Variablen im Controller übergeben. Um auch nur die Ids der Opps zu übertragen, welche ich auch angeklickt habe, benötige ich zusätzlich noch etwas JavaScript. Damit ich das Ganze dann auch automatisch zur Anzeige bringe, benötige ich einen zusätzlichen Rerender-Befehl oder muss die Seite neu laden.
Lösungsvorschlag
Oder ich löse das Problem allein über eine statische Funktion im Controller und einem Javascript-Befehl auf meiner Visualforce-Seite. Und so sieht das dann aus:
Es ist zu beachten, dass die Funktion des Controllers statisch ist und mit der Annotation “@RemoteAction” gekennzeichnet wird. Daraufhin kann ich eine JavaScript-Funktion definieren, welche über die Syntax Controllername.Funktionsname(Parameter 1, Parameter 2, …, Callback Funktion) diese Funktion aufruft (Salesforce HowTo).
Für das Beispiel bedeutet dies folgendes:
Zuerst wird die id meiner angewählten Opportunities ausgelesen, und in einem Array gespeichert. Daraufhin startet eine Spinner-Animation, um dem User zu signalisieren, dass eine kurze Wartezeit folgt, in der die Funktion setOpportunityClosedLost des Controllers aufgerufen wird. Diese rufe ich auf, indem ich schlicht die Controller-Klasse referenziere und dann die Funktion mit einem Punkt getrennt anhänge. Als Parameter wird das ID Array übergeben. Zusätzlich übergebe ich eine Funktion, die den Callback des Datenbankaufrufes verarbeiten soll. Ich unterscheide drei Fälle:
- Der Aufruf ist erfolgreich.
- Der Controller wirft eine Exception
- Ein unbekannter Fehler tritt auf
In jedem Fall definiere ich, was passieren soll, wenn dieser Fall eintritt. Der Einfachheit halber, lade ich in diesem Beispiel die Seite schlichtweg neu. Um das Neuladen der Seite zu vermeiden, ließe sich beispielsweise der Inhalt des tableBody Tag mithilfe der innerHTML Funktion überschreiben. Wird eine Exception vom Controller geworfen, oder erfolgt ein anderer Fehler, wird dies dem Benutzer über eine Alert Box signalisiert. Auch die Fehlerabfragen könnten in einem dafür angelegten <div> gerendert werden, beispielsweise über eine Notification Box (Link)

Haben Sie Fragen oder Anregungen? Verfassen Sie einen Kommentar oder melden Sie sich per Mail bei info@mind-force.de. Unser Team wird Ihnen schnellstmöglich antworten.