Wann muss ich bei der Migration von Visualforce-Seiten zu Lightning tatsächlich Code anwenden?

In unserem ersten Teil von Visualforce und Lightning haben wir uns detailliert damit befasst, wie eine Migration von Visualforce-Seiten zu Lightning mit „Salesforce-Bordmitteln“ umgesetzt werden kann. Dabei haben wir auf Standard-Lightning-Komponenten wie z.B. den Lightning Experience Visualforce Report zurückgegriffen.

In Teil 2 wollen wir nun eine Stufe weitergehen:

Wann muss ich mich mit dem Code der Visualforce-Seite auseinandersetzen?

Der Lightning Experience Visualforce Report hat bei einigen Visualforce-Seiten aufgezeigt, dass es zu Problemen wegen des JavaScript window-Objektes und dem HTML anchor-Attribut HREF kommen kann.

Beide werden für die Navigation zwischen den Seiten bzw. Weiterleitungen zu Seiten - oft mit Hilfe von dynamischen Verlinkungen - eingesetzt. D.h. also, wir müssen uns das JavaScript window-Objekt und die HREF-Attribute genauer anschauen.

DIE PROBLEMSTELLUNG IN KÜRZE

Grundsätzlich: In Salesforce Classic und Lightning sind Seiten nach komplett unterschiedlichen Modellen aufgebaut, die sich essentiell auf das Navigieren innerhalb der Salesforce Org auswirken:

  • In Salesforce Classic werden immer ganze Seiten geladen, egal ob ich die Seite aufrufe, einen Datensatz bearbeite oder speichere. Alle Informationen werden vom Server abgerufen oder an den Server gesendet.
  • In Lightning hingegen ist eine Seite ein Container für unterschiedlichste Komponenten. Diese Komponenten werden über HTML-IFrames voneinander abgegrenzt, so dass alle Interaktionen nur im Browser stattfinden. Das bedeutet: statt eine neue Seite zu laden, werden Inhalte in den Container der Komponente geladen.

Erste notwendige anpassungen: das WINDOW-OBJEKT

Für das Navigieren bzw. Weiterleiten oder Aufrufen von Visualforce-Seiten wird oft das globale JavaScript window-Objekt genutzt.  Nach der oben beschriebenen Lightning-Komponenten-Logik geht das aber schlicht nicht mehr:

Die Visualforce-Seite auf der Lightning-Seite hat kein Recht und auch keine Möglichkeit, die aktuelle Seite mithilfe von window zu verändern (insofern wir „sauber“ arbeiten). Ihr Wirkungsbereich bezieht sich nur auf den IFrame, in der sie dargestellt wird. Natürlich wollen wir aber trotzdem, dass unsere Visualforce-Seite eine andere Seite aufruft - da ist es erst mal egal, ob wir zur Seite weitergeleitet werden oder diese eben im Komponenten-Container dargestellt wird. 

Um dem neuen Navigationsmodell zu folgen, stellt uns Salesforce das sforce.one-Utility Object ("Dienstprogrammobjekt") zur Verfügung, mit welchem wir zu URLs, Datensätzen, Feeds, Listen oder auch einfach nur "zurück" navigieren können.

Dieses sforce.one-Objekt wird automatisch zu jeder Lightning-Seite hinzugefügt: die einzelnen Komponenten dürfen darüber auf den Lightning Container (URL: /one/one.app ) zugreifen und die Navigation (welche Seite dargestellt wird) beeinflussen.

Konkret sieht das dann so aus: Wir wollen die Seite "Map" aufrufen. Der entsprechende Code lautet dann: sforce.one.navigateToURL("/apex/Map");. 

Weitere Anpassungen: das HREF-ATTRIBUT

Bei der Meldung zum HREF-Attribut schlägt der Report auf Seiten-Aktualisierungen mithilfe von $CurrentPage.parameters.id an. Es wurde also die Id der aktuellen Seite abgefragt, mit dem Ziel diese Seite zu aktualisieren.

Warum das in Lightning nicht funktionieren kann, erklärt sich nun quasi von selbst:

Die Visualforce-Seite im IFrame kennt die Id in der /one/one.app nicht – daher können wir die globale $CurrentPage-Variable nicht nutzen. Denn sie wird immer nur die Daten der eingebetteten Visualforce-Seite, nie die ID im Lightning Container (der Seite), kennen.

An dieser Stelle macht es Lightning uns aber relativ einfach: Auf jeder Seite können wir aus jeder Komponente heraus die Variable recordId abrufen. Hier ändert sich also zusätzlich zum Dienstprogramm im Prinzip nur der Name der Variablen:
sforce.one.navigateToSObject(recordId);. 

Daraus ergeben sich folgende Problemstellungen:

Erstens, sforce.one ist in Classic nicht verfügbar. Um die Navigation also auf beiden Plattformen zu gewährleisten, benötigt man Abfragen, auf welchem UserTheme die Seite ausgeführt wird. Diese Abfragen können über Apex, Visualforce oder JavaScript implementiert werden.  

Zweitens, als besonderen Spaß für alle, die Teile der /one/one.app-URL hardcoded eingebunden haben: Mit dem Summer '18 Release wird Salesforce die Lightning URL umstellen.

Weitere Limits

Es gibt auch Fälle, in denen man weit aufwändigere Anpassungen vornehmen muss oder sich gänzlich von einer Lösung mit Visualforce verabschieden sollte.

Für unsere Seiten sind wir nur einmal an ein solches Limit gestoßen, nämlich bei der Apex enhancedList-Komponente, die uns Listenansichten von Objekten generiert und von Lightning nicht unterstützt wird. Da helfen auch keine Lightning-Stylesheets, das muss für Lightning neu programmiert werden.

Ein weiteres Limit bezieht sich auf die relatedList Apex-Komponente und auf die Weitergabe von Feldwerten an den Controller und/oder andere Visualforce-Seiten, daher empfiehlt es sich eher, mit Lightning Components zu arbeiten.

Zudem funktioniert die IFrame-Apex-Komponente zwar noch, es empfiehlt sich aber, z.B. auf Canvas umzustellen, statt einen IFrame im IFrame zu implementieren.

Laut Salesforce ist es in Lightning nicht möglich, Kopfzeile und Navigationsmenü zu unterdrücken (obwohl genau das gelegentlich bei noch nicht Lightning-optimierten Visualforce-Seiten unbeabsichtigt passiert). Und dass die Classic-Kopfzeile und -Randleiste immer unterdrückt werden, erklärt sich auch fast von selbst.

Fazit

Abschließend können wir sagen, dass tatsächlich fast alles in Lightning auch mit Visualforce-Seiten funktioniert. Eine Migration zu Lightning Components ist also nicht zwangsläufig notwendig. Allerdings sollte einem dabei bewusst sein, dass es nicht immer die Frage ist, OB eine Visualforce-Seiten in Lightning funktioniert, sondern WIE sie funktioniert und ob das ausreichend ist.

Für komplexe Seiten oder Seiten, auf denen viel interagiert wird (viele Nutzereingaben und -aktionen), sollte aber definitiv evaluiert werden, ob langfristig eine Lösung mit dem Lightning Components Framework doch zweckmäßiger ist. Sie würden zusätzlich von einer besseren Performance profitieren, da viele Server-Anfragen wegfallen, und selbstverständlich auch von einer besseren Usability, da sich Lightning Components per Definition besser in Lightning Experience einfügen. 

Ressourcen

Zurück zur Artikelübersicht

Teilen Sie diesen Artikel