Einführung in die Erstellung einer Codekomponente
Power Apps bietet zahlreiche integrierte Funktionen für App-Entwickler zum Erstellen ihrer Apps. Manchmal müssen Sie jedoch benutzerdefinierte Benutzererlebnisse erstellen, um Ihren individuellen Anforderungen gerecht zu werden. Zu den Beispielen gehören das Ersetzen eines Prozentwerts durch ein Messgerät, das Rendern eines Barcodes anstelle einer ID oder das Ersetzen vorhandener Steuerelemente durch Steuerelemente mit mehr Funktionen, z. B. eine Drag & Drop-Rasteransicht. Sie können auch das Power Apps Component Framework um vorhandene Komponenten entwickeln, die Sie in anderen Web-Frameworks wie React oder Angular geschrieben haben.
Durch das Erstellen dieser Komponenten können Sie die gesamte Breite des modernen Web-Entwicklungsökosystems nutzen: die Bibliotheken, Frameworks und anderen Tools, mit denen Sie möglicherweise vertraut sind. Zudem können Sie diese Funktionen in eine Form packen, mit der App-Entwickler Apps mit Ihrem Code erstellen können wenn es ein sofort einsatzbereites Teil der Plattform wäre.
Hinweis
Es sind auch andere Beispielkomponenten – einschließlich solcher, die Angular oder React verwenden. verfügbar.
Benutzerdefinierte Power Apps-Komponenten werden häufig als Codekomponenten bezeichnet, da sie zur Erstellung von benutzerdefiniertem Code benötigen. Sie bestehen aus drei Elementen: einem Manifest, einer Implementierung und Ressourcen.
In der folgenden Übung erstellen Sie eine benutzerdefinierte Codekomponente, um ein Szenario für Ihr Unternehmen zu verarbeiten. Ihr Unternehmen möchte, dass einige Felder im Formular in der Anwendung schreibgeschützt sind, bis der Benutzer eine Bearbeitung des Datenwerts manuell einleitet. Das Team hat ermittelt, dass keines der integrierten Steuerelemente funktioniert, und hat Sie daher gebeten, eine benutzerdefinierte Codekomponente zu erstellen.
Erstellen Sie eine benutzerdefinierte bearbeitbare Feldkomponente, die wie im folgenden Bild aussieht, um diese Anforderung zu lösen. Der Wert ist schreibgeschützt, bis der Benutzer die Option „Bearbeiten“ auswählt.
Diese Komponente erfasst Änderungen, die von der Host-App stammen, und ermöglicht es dem Benutzer, Änderungen vorzunehmen, die dann an die Host-App übertragen werden. Die folgenden Schritte helfen Ihnen bei der Erstellung dieser Komponente.
Power Platform CLI installieren
Führen Sie die folgenden Schritte aus, um Ihren Computer darauf vorzubereiten, Codekomponenten zu erstellen:
Installieren Sie Node.js (wird mit npm bereitgestellt). Wir empfehlen Ihnen, eine LTS-Version (Long-Term Support) zu verwenden, wie hier. Sie sollten prüfen, ob Node/NPM bereits installiert ist. Wechseln Sie zu diesem Zweck zu einer Eingabeaufforderung, und geben Sie folgenden Text ein:
// Launch a standard command prompt and type both of the following npm --version Node --version
Sollte eine Fehlermeldung angezeigt werden, wenn Sie diese Befehle ausführen, müssen Sie über die Links oben Node.js installieren.
Bei einer erfolgreichen Installation von Node werden beim Eingeben der obigen Befehle die Versionsnummern im Befehlsfenster zurückgegeben, wie unten zu sehen:
// If installed properly you will see something like the output below. The version numbers may be slightly different based on the version installed. C:\npm --version 10.5.0 C:\Node --version v20.12.2
Installieren Sie Visual Studio Code.
Installieren Sie Power Platform Tools-Erweiterung. Stellen Sie sicher, dass Sie die Visual Studio Code-Installation abgeschlossen haben, bevor Sie die Power Platform Tools installieren.
Die Power Platform Tools erlauben nicht die Ausführung von CLI-Befehlen für Power Platform in einer Eingabeaufforderung außerhalb von Visual Studio Code. Es wird empfohlen, dass Sie zudem das CLI-MSI für Power Platform installieren.
Folgen Sie diesen Anweisungen, um die CLI auf Windows-Ebene zu installieren. Sie können die CLI und die Power Platform Tools-Erweiterung gleichzeitig installieren.
Neues Komponentenprojekt erstellen
Prüfen Sie, ob die oben aufgeführten installierten Komponenten korrekt funktionieren, bevor Sie damit beginnen, Komponenten zu erstellen. NPM‑ und CLI-Befehle funktionieren über ein Terminalfenster in Visual Studio Code. Wenn bei der korrekten Ausführung in VS Code Probleme auftreten, können Sie die in den folgenden Schritten angegebenen Terminalbefehle in einer Eingabeaufforderung ausführen, wenn Sie die CLI für Power Platform installiert haben.
Navigieren Sie in Visual Studio Code zu Terminal > Neues Terminal (oder drücken Sie STRG+UMSCHALT+`). Wiederholen Sie im Terminalfenster in VS Code die Anweisungen npm und Node Version. Wenn alles die richtigen Versionsnummern zurückgibt, können Sie damit fortfahren, die Lösung zu erstellen.
// Test installs from Steps 1-3 listed above
// This will verify NPM installation
C:\npm --version
10.5.0
// This will verify Node installation
C:\Node --version
v20.12.2
// This will launch Visual Studio Code from the command line.
C:\Code
Jetzt können Sie ein neues Komponentenprojekt erstellen. Führen Sie zunächst folgende Schritte aus:
Legen Sie ein Verzeichnis an, in dem Sie Ihre Komponente erstellen. In diesem Beispiel legen Sie die Komponente unter C:\source\Editable-pcf ab. Für die Erstellung eines eigenen Verzeichnisses verwenden Sie Visual Studio Code. Alternativ können Sie die Ordner mit der Eingabeaufforderung erstellen, wenn Sie Probleme mit der Verwendung des VS Code-Terminals haben.
Starten Sie Visual Studio Code.
Wählen Sie Terminal und dann Neues Terminal aus.
Ihre Terminalsitzung wird standardmäßig auf den Ordner umgeschaltet, der zuletzt verwendet wurde. Dies wird im Eingabeaufforderungsbereich um TERMINAL wie unten dargestellt angezeigt:
//Note Your PS will not list exactly what is seen below, but will be specific to your starting path. PS C:\Users\Name\Folder
Wechseln Sie zu dem Verzeichnis, in dem diese Lösung erstellt werden soll. Mit dem Befehl „CD“ können Sie zu einem geeigneten Ort wechseln.
Hinweis
Denken Sie daran, dass der Ordner wichtig ist, in dem Sie NPM oder andere Befehle ausführen. Stellen Sie stets sicher, dass Sie sich in Ihrem Projektordner befinden, bevor Sie Build-Befehle ausführen. Andernfalls kann der Build beschädigt werden und es kann zu Problemen beim Erzielen optimaler Ergebnisse kommen.
Verwenden Sie md (make directory), wie unten in Ihrem VS Code-Terminalfenster gezeigt, um einen neuen Ordner am Standardspeicherort zu erstellen.
md source cd source
So wird ein Verzeichnis mit dem Namen „Source“ erstellt und Sie werden mit dem Befehl „cd“ (Verzeichnis ändern) zu diesem Verzeichnis weitergeleitet.
Erstellen Sie aus Ihrem Quellverzeichnis ein Verzeichnis mit dem Namen editable-pcf. Dies wird Ihr PROJEKT-Verzeichnis, in dem alle Ihre Projektdateien gespeichert werden. Wir passen auch das Verzeichnis in unser neues Projektverzeichnis an.
md editable-pcf cd editable-pcf
Initialisieren Sie Ihr Komponentenprojekt mit der Power Platform CLI über den folgenden Befehl:
pac pcf init --namespace SampleNamespace --name EditablePCF --template field
Das folgende Bild zeigt ein Beispiel für die Ausgabe, die angezeigt werden sollte.
Achtung
Wenn der PAC PCF INIT-Befehl nicht in einem Terminalfenster in VS Code ausgeführt wird und Sie den Power Platform CLI installiert haben, können Sie eine Eingabeaufforderung ausführen und eine CD Ihrem editable-pcf-Verzeichnis hinzufügen. Sobald Sie dort sind, können Sie den Befehl in die Eingabeaufforderung eingeben und er wird korrekt funktionieren. Es sollte Ihnen dann die gleiche Ausgabe wie oben aufgeführt angezeigt werden.
Installieren Sie die Projekterstellungstools mit dem Befehl
npm install
. Möglicherweise werden einige Warnungen angezeigt. Sie können sie jedoch ignorieren. Stellen Sie sicher, dass Sie sich in Ihrem PROJECT-Verzeichnis befinden, bevor Sie diesen Befehl eingeben.npm install
Achtung
Wenn npm install nicht in einem Terminalfenster in VS Code ausgeführt wird und Sie den Power Platform CLI installiert haben, können Sie eine Eingabeaufforderung ausführen und eine CD Ihrem editable-pcf-Verzeichnis hinzufügen. Sobald Sie dort sind, können Sie den Befehl in die Eingabeaufforderung eingeben und er wird korrekt funktionieren.
Sie können prüfen, ob alles funktioniert, indem Sie einen DIR-Befehl im Terminalfenster in VS Code oder in der Eingabeaufforderung ausführen, wenn Sie sich für die Erstellung außerhalb von Visual Studio Code entschieden haben. Sie sollten in Ihrem editable-pcf-Verzeichnis eine Reihe von Dateien und Ordnern haben. Dies ist das Projekt, das Sie über die Schritte oben erstellt haben und das wir mit VS Code erstellen werden.
Führen Sie den folgenden Befehl aus, um das Projekt in Visual Studio Code zu öfnen oder wenn Sie eine Eingabeaufforderung im Eingabeaufforderungsfenster verwenden. Dadurch sollte Ihr erstelltes Projekt in VS Code gestartet werden.
code -a .
Die Projektinhalte sollten nun wie im Bild unten aussehen.
Manifest Ihrer Codekomponente aktualisieren
Aktualisieren Sie die Manifestdatei, damit Ihr Steuerelement korrekt dargestellt wird.
Erweitern Sie den Ordner EditablePCF, und öffnen Sie die Datei ControlManifest.Input.xml.
Ändern Sie die Version in 1.0.0 und den description-key in Edits project name.
Suchen Sie den Knoten property.
Ändern Sie den Namenswert in Name, den Anzeigename-Schlüssel in Name und den Beschreibungsschlüssel in A name.
Suchen Sie den Knoten resources.
Schließen Sie eine Referenz zu einer CSS-Datei mit dem Namen editable-pcf.css ein, die Sie in den Schritten unten erstellen werden.
<css path="css/EditablePCF.css" order="1" />
Speichern Sie Ihre Änderungen durch Auswahl von Datei und Speichern, oder drücken Sie STRG+S, um die Datei zu speichern.
Ihrer Codekomponente Stil hinzufügen
Gehen Sie wie folgt vor, um Ihrer Codekomponente einen Stil hinzuzufügen:
Stellen Sie sicher, dass die Datei ControlManifest.Input.xml noch ausgewählt ist, und klicken Sie dann auf Neuer Ordner.
Nennen Sie den neuen Ordner css.
Wählen Sie den von Ihnen erstellten Ordner css aus, und klicken Sie dann auf Neue Datei.
Geben Sie der neuen Datei den Namen EditablePCF.css (oder wie auch immer Sie die CSS-Datei in Schritt 6 oben genannt haben).
Öffnen Sie die neu erstellte Datei „EditablePCF.css“, und fügen Sie den Ausschnitt CSS ein. Dies ist der Ressourcenreferenzname, den Sie zuvor verwendet haben, als Sie den CSS-Pfadcode der Manifestdatei hinzugefügt haben.
.SampleNamespace\.HelloPCF { font-size: 1.5em; }
Der Inhalt der Datei CSS sollte nun wie im Bild unten aussehen.
Wählen Sie Datei und dann Speichern aus, oder drücken Sie STRG+S, um die Datei zu speichern.
Codekomponente erstellen
Bevor Sie Ihre Komponentenlogik implementieren können, müssen Sie für Ihre Komponente einen Build ausführen. So wird sichergestellt, dass die richtigen TypeScript-Typen generiert werden, die den Eigenschaften in Ihrem ControlManifest.xml-Dokument entsprechen.
Kehren Sie zum Terminal in VS Code zurück, und erstellen Sie Ihr Projekt mithilfe des folgenden Befehls. Wenn Sie aus irgendeinem Grund Probleme mit der Verwendung von Terminal in Visual Studio Code haben: Sie können über die Eingabeaufforderung zu Ihrem Ordner navigieren und den Befehl von dort aus ausführen.
Achtung
Stellen Sie sicher, dass Sie sich in Ihrem PROJECT-Verzeichnis in Ihrem Terminal befinden, bevor Sie diesen Befehl eingeben.
npm run build
Die Komponente wird im Ordner out/controls/EditablePCF kompiliert. Die Buildartefakte umfassen:
css-Ordner
bundle.js – Gebündelter Quellcode der Komponente
ControlManifest.xml – Tatsächliche Manifestdatei der Komponente, die in die Organisation Microsoft Dataverse hochgeladen wird
Warnung
Der häufigste Fehler ist ein Tippfehler im Dateinamen für die CSS-Datei, die Sie zuvor erstellt haben. Wenn das passiert, benennen Sie die Dateien einfach entsprechend um und führen Sie den Befehl „npm run Build“ erneut aus, bis er ohne Fehler ausgeführt wurde. Vergleichen Sie den Abschnitt RESOURCE in der Datei COntrolManifest.Input.xml mit der Datei, die im CSS-Ordner erstellt ist. Sie müssen zu 100 % übereinstimmen.
Logik der Codekomponente implementieren
Gehen Sie folgendermaßen vor, sobald der Build mit den obigen Schritten abgeschlossen ist, um die Logik Ihrer Codekomponente zu implementieren. Suchen Sie im Visual Studio Code im EXPLORER nach einer Datei namens Index.ts. Dort beginnen wir mit dem Schreiben des Codes für unsere Komponente.
Öffnen Sie die Datei index.ts in Visual Studio Code.
Fügen Sie über der Methode constructor die folgenden privaten Variablen ein:
// The PCF context object\ private context: ComponentFramework.Context<IInputs>; // The wrapper div element for the component\ private container: HTMLDivElement; // The callback function to call whenever your code has made a change to a bound or output property\ private notifyOutputChanged: () => void; // Flag to track if the component is in edit mode or not\ private isEditMode: boolean; // Tracking variable for the name property\ private name: string | null;
Suchen Sie die Methode public init, und ersetzen Sie sie durch die folgende.
public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container: HTMLDivElement) { // Track all the things this.context = context; this.notifyOutputChanged = notifyOutputChanged; this.container = container; this.isEditMode = false; // Create the span element to hold the project name const message = document.createElement("span"); message.innerText = `Project name ${this.isEditMode ? "" :context.parameters.Name.raw}`; // Create the textbox to edit the name const text = document.createElement("input"); text.type = "text"; text.style.display = this.isEditMode ? "block" : "none"; if (context.parameters.Name.raw) { text.value = context.parameters.Name.raw; // Wrap the two above elements in a div to box out the content const messageContainer = document.createElement("div"); messageContainer.appendChild(message); messageContainer.appendChild(text); // Create the button element to switch between edit and read modes const button = document.createElement("button"); button.textContent = this.isEditMode ? "Save" : "Edit"; button.addEventListener("click", () => { this.buttonClick(); }); // Add the message container and button to the overall control container this.container.appendChild(messageContainer); this.container.appendChild(button); } }
Warnung
Möglicherweise sehen Sie, dass der EventListener für den ButtonClick rot unterstrichen ist. Keine Sorge, wir erstellen weiter unten für dieses Ereignis die Methode. Wenn andere Abschnitte rot markiert angezeigt werden, sollten Sie überprüfen, ob alles richtig kopiert oder eingegeben wurde.
Fügen Sie die Schaltflächenauswahl-Handler-Methode hinzu. Fügen Sie unter der init-Methode die folgende Methode hinzu.
public buttonClick() { // Get our controls via DOM queries const text = this.container.querySelector("input")!; const message = this.container.querySelector("span")!; const button = this.container.querySelector("button")!; // If not in edit mode, copy the current name value to the textbox if (!this.isEditMode) { text.value = this.name ?? ""; } else if (text.value != this.name) { // if in edit mode, copy the textbox value to name and call the notify callback this.name = text.value; this.notifyOutputChanged(); } // flip the mode flag this.isEditMode = !this.isEditMode; // Set up the new output based on changes message.innerText = `Project name ${this.isEditMode ? "" : this.name}`; text.style.display = this.isEditMode ? "inline" : "none"; text.value = this.name ?? ""; button.textContent = this.isEditMode ? "Save" : "Edit"; }
Suchen Sie die Methode updateView, und ersetzen Sie sie durch die folgende.
public updateView(context: ComponentFramework.Context<IInputs>): void { // Checks for updates coming in from outside this.name = context.parameters.Name.raw; const message = this.container.querySelector("span")!; message.innerText = `Project name ${this.name}`; }
Suchen Sie den Ersatz getOutputs, und ersetzen Sie ihn durch die folgende Methode.
public getOutputs(): IOutputs { return { // If our name variable is null, return undefined instead Name: this.name ?? undefined }; }
Suchen Sie die Methode „destroy“, und ersetzen Sie sie durch die folgende.
public destroy() { // Remove the event listener we created in init this.container.querySelector("button")!.removeEventListener("click", this.buttonClick); }
Ihre finale Datei Index.ts sollte nun wie im folgenden Code aussehen:
import { IInputs, IOutputs } from "./generated/ManifestTypes"; export class EditablePCF implements ComponentFramework.StandardControl<IInputs, IOutputs> { /** * Empty constructor. */ // The PCF context object\ private context: ComponentFramework.Context<IInputs>; // The wrapper div element for the component\ private container: HTMLDivElement; // The callback function to call whenever your code has made a change to a bound or output property\ private notifyOutputChanged: () => void; // Flag to track if the component is in edit mode or not\ private isEditMode: boolean; // Tracking variable for the name property\ private name: string | null; constructor() { } /** * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here. * Data-set values are not initialized here, use updateView. * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions. * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously. * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface. * @param container If a control is marked control-type='standard', it will receive an empty div element within which it can render its content. */ public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container: HTMLDivElement) { // Track all the things this.context = context; this.notifyOutputChanged = notifyOutputChanged; this.container = container; this.isEditMode = false; // Create the span element to hold the project name const message = document.createElement("span"); message.innerText = `Project name ${this.isEditMode ? "" :context.parameters.Name.raw}`; // Create the textbox to edit the name const text = document.createElement("input"); text.type = "text"; text.style.display = this.isEditMode ? "block" : "none"; if (context.parameters.Name.raw) { text.value = context.parameters.Name.raw; // Wrap the two above elements in a div to box out the content const messageContainer = document.createElement("div"); messageContainer.appendChild(message); messageContainer.appendChild(text); // Create the button element to switch between edit and read modes const button = document.createElement("button"); button.textContent = this.isEditMode ? "Save" : "Edit"; button.addEventListener("click", () => { this.buttonClick(); }); // Add the message container and button to the overall control container this.container.appendChild(messageContainer); this.container.appendChild(button); } } public buttonClick() { // Get our controls via DOM queries const text = this.container.querySelector("input")!; const message = this.container.querySelector("span")!; const button = this.container.querySelector("button")!; // If not in edit mode, copy the current name value to the textbox if (!this.isEditMode) { text.value = this.name ?? ""; } else if (text.value != this.name) { // if in edit mode, copy the textbox value to name and call the notify callback this.name = text.value; this.notifyOutputChanged(); } // flip the mode flag this.isEditMode = !this.isEditMode; // Set up the new output based on changes message.innerText = `Project name ${this.isEditMode ? "" : this.name}`; text.style.display = this.isEditMode ? "inline" : "none"; text.value = this.name ?? ""; button.textContent = this.isEditMode ? "Save" : "Edit"; } /** * Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc. * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions */ public updateView(context: ComponentFramework.Context<IInputs>): void { // Checks for updates coming in from outside this.name = context.parameters.Name.raw; const message = this.container.querySelector("span")!; message.innerText = `Project name ${this.name}`; } /** * It is called by the framework prior to a control receiving new data. * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as "bound" or "output" */ public getOutputs(): IOutputs { return { // If our name variable is null, return undefined instead Name: this.name ?? undefined }; } /** * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup. * i.e. cancelling any pending remote calls, removing listeners, etc. */ public destroy() { // Remove the event listener we created in init this.container.querySelector("button")!.removeEventListener("click", this.buttonClick); } }
Codekomponente neu erstellen und ausführen
Gehen Sie wie folgt vor, um die Codekomponente neu zu erstellen und auszuführen:
Nachdem die Logik Ihrer Komponente implementiert wurde, kehren Sie zum Terminal zurück, um die Komponente über den unten stehenden Befehl neu zu erstellen. Sie können dies direkt in VS Code oder über die Eingabeaufforderung ausführen, solange Sie zuerst zu Ihrem Ordner editable-pcf wechseln.
npm run build
Die Erstellung sollte erfolgreich sein.
Führen Sie Ihre Komponente über den unten stehenden Befehl in der Testumgebung des Node aus. Wenn Sie dies noch nicht getan haben, sollte ein Browser mit der Anzeige Ihrer neu erstellten Komponente gestartet werden.
npm start
Hinweis
Sie können auch den Überwachungsmodus aktivieren, um sicherzustellen, dass Änderungen an den folgenden Ressourcen automatisch vorgenommen werden, ohne dass die Testumgebung mithilfe von
npm start watch
neu gestartet werden muss.index.ts-Datei
ControlManifest.Input.xml-Datei
Importierte Bibliotheken in index.ts
Alle in der Manifestdatei aufgeführten Ressourcen
Ein neues Browserfenster sollte die Testumgebung laden. (Das Fenster sollte sich automatisch öffnen, Sie können jedoch auch auf die im Befehlsfenster gefundene Adresse verweisen).
Wählen Sie Bearbeiten aus.
Geben Sie Project One ein, und klicken Sie auf Speichern.
Sie können die Containergröße anpassen.
Die Testumgebung sollte nun wie im Bild unten aussehen.
Schließen Sie das Testumgebungs-Browserfenster.
Wechseln Sie zurück zum Terminal oder Ihrer Eingabeaufforderung (wenn Sie nicht das VS Code-Terminal verwenden) und stoppen Sie den Watcher, indem Sie [STRG] + C gedrückt halten.
Geben Sie Y ein und dann [ENTER].