Erstellen benutzerdefinierter Steuerelemente für den Eigenschaftenbereich
Das SharePoint-Framework enthält eine Reihe von Standardsteuerelementen für den Eigenschaftenbereich. Manchmal jedoch benötigen Sie zusätzliche Funktionen, die über die grundlegenden Steuerelemente hinausgehen. Vielleicht sollen beispielsweise die Daten in einem Steuerelement oder einer bestimmten Benutzeroberfläche asynchron aktualisiert werden. Dann können Sie ein benutzerdefiniertes Steuerelement für den Eigenschaftenbereich erstellen, um die benötigten Funktionen zu implementieren.
In diesem Artikel erstellen Sie ein benutzerdefiniertes Dropdown-Steuerelement, das seine Daten asynchron aus einem externen Dienst lädt, ohne die Benutzeroberfläche des Webparts zu blockieren.
Der Quellcode des Webparts, mit dem wir arbeiten, steht auf GitHub zur Verfügung, unter sp-dev-fx-webparts/samples/react-custompropertypanecontrols.
Hinweis
Bevor Sie die Anleitung in diesem Artikel umsetzen können, müssen Sie eine Entwicklungsumgebung einrichten, in der Sie SharePoint-Framework-Lösungen erstellen können.
Erstellen eines neuen Projekts
Erstellen Sie zunächst einen neuen Ordner für Ihr Projekt:
md react-custompropertypanecontrol
Wechseln Sie in den Projektordner:
cd react-custompropertypanecontrol
Führen Sie im Projektordner den SharePoint Framework-Yeoman-Generator aus, um ein Gerüst für ein neues SharePoint Framework-Projekt zu erstellen:
yo @microsoft/sharepoint
Wenn Sie dazu aufgefordert werden, geben Sie die folgenden Werte ein (wählen Sie für alle unten nicht aufgeführten Eingabeaufforderungen die Standardoption aus):
- Welchen Typ von clientseitiger Komponente möchten Sie erstellen? WebPart
- Wie lautet der Name Ihres Webparts? Elemente auflisten
- Welche Vorlage möchten Sie verwenden? React
Öffnen Sie den Projektordner in einem Code-Editor.
Definieren der Webparteigenschaft zum Speichern der ausgewählten Liste
In dem Webpart, das Sie erstellen, werden Listenelemente aus der jeweils ausgewählten SharePoint-Liste angezeigt. Benutzer können die gewünschte Liste in den Eigenschaften des Webparts auswählen. Erstellen Sie eine neue Webparteigenschaft namens "listName
", um die ausgewählte Liste zu speichern:
Öffnen Sie im Code-Editor die Datei src/webparts/listItems/ListItemsWebPartManifest.json. Ersetzen Sie die standardmäßige
description
-Eigenschaft durch eine neue Eigenschaft namens "listName
":{ ... "preconfiguredEntries": [{ ... "properties": { "listName": "" } }] }
Öffnen Sie die Datei src/webparts/listItems/ListItemsWebPart.ts, und aktualisieren Sie die
IListItemsWebPartProps
Schnittstelle wie folgt:export interface IListItemsWebPartProps { description: string; listName: string; }
Ändern Sie in der Datei src/webparts/listItems/ListItemsWebPart.ts die Methode "
render()
" wie folgt:export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... public render(): void { const element: React.ReactElement<IListItemsProps> = React.createElement( ListItems, { listName: this.properties.listName, description: this.properties.description, isDarkTheme: this._isDarkTheme, environmentMessage: this._environmentMessage, hasTeamsContext: !!this.context.sdks.microsoftTeams, userDisplayName: this.context.pageContext.user.displayName } ); ReactDom.render(element, this.domElement); } // ... }
Aktualisieren Sie die Methode
getPropertyPaneConfiguration()
wie folgt:export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { return { pages: [ { header: { description: strings.PropertyPaneDescription }, groups: [ { groupName: strings.BasicGroupName, groupFields: [ PropertyPaneTextField('listName', { label: strings.ListFieldLabel }) ] } ] } ] }; } // ... }
Fügen Sie in der Datei src/webparts/listItems/loc/mystrings.d.ts eine neue Eigenschaft
ListFieldLabel
vom Typstring
der vorhandenenIListItemsWebPartStrings
Schnittstelle hinzu:declare interface IListItemsWebPartStrings { PropertyPaneDescription: string; BasicGroupName: string; .. ListFieldLabel: string; }
Fügen Sie in der Datei src/webparts/listItems/loc/en-us.js eine neue Eigenschaft
ListFieldLabel
für das zurückgegebene Objekt hinzu:define([], function() { return { "PropertyPaneDescription": "Description", "BasicGroupName": "Group Name", ... "ListFieldLabel": "List" } });
Öffnen Sie die Datei src/webparts/listItems/components/IListItemsProps.ts, und fügen Sie die
listName
Eigenschaft der Listenschnittstelle hinzu:export interface IListItemsProps { description: string; isDarkTheme: boolean; environmentMessage: string; hasTeamsContext: boolean; userDisplayName: string; listName: string; }
Ändern Sie in der Datei src/webparts/listItems/components/ListItems.tsx die Inhalte der Methode "
render()
" wie folgt:export default class ListItems extends React.Component<IListItemsProps, {}> { public render(): React.ReactElement<IListItemsProps> { const { description, isDarkTheme, environmentMessage, hasTeamsContext, userDisplayName, listName } = this.props; return ( <section className={`${styles.listItems} ${hasTeamsContext ? styles.teams : ''}`}> <div className={styles.welcome}> <img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} /> <h2>Well done, {escape(userDisplayName)}!</h2> <div>{environmentMessage}</div> <div>List name: <strong>{escape(listName)}</strong></div> </div> </section> ); } }
Führen Sie den folgenden Befehl aus, um zu überprüfen, ob das Projekt ausgeführt wird:
gulp serve
Fügen Sie im Webbrowser das Listenelement-Webpart zum Zeichenbereich hinzu, und öffnen Sie die Eigenschaften. Überprüfen Sie, dass der für die List-Eigenschaft festgelegte Wert im Webparttext angezeigt wird.
Erstellen eines asynchronen Steuerelements für den Dropdown-Eigenschaftenbereich
Das SharePoint Framework bietet Ihnen ein standardmäßiges Dropdown-Steuerelement, mit dem Benutzer einen bestimmten Wert auswählen können. Das Dropdown-Steuerelement wurde so konzipiert, dass all seine Werte vorab bekannt sein müssen. Wenn Sie die Werte dynamisch laden möchten oder Werte asynchron aus einem externen Dienst laden und nicht das gesamte Webpart blockieren möchten, ist das Erstellen eines benutzerdefinierten Dropdownsteuerelements eine Option.
Wenn Sie ein benutzerdefiniertes Eigenschaftenbereichssteuerelement erstellen, das React im SharePoint Framework verwendet, besteht das Steuerelement aus einer Klasse, die das Steuerelement bei dem Webpart registriert, und einer React-Komponente, die das Dropdown rendert und seine Daten verwaltet.
Hinzufügen eines React-basierten asynchronen Dropdown-Steuerelements zum Eigenschaftenbereich
Erstellen Sie einen Ordner „components“. Erstellen Sie dazu im Ordner src eine Hierarchie aus drei neuen Ordnern, sodass Ihre Ordnerstruktur als src/controls/PropertyPaneAsyncDropdown/components angezeigt wird.
Definieren Sie die Eigenschaften der asynchronen React-basierten Dropdownkomponente. Erstellen Sie dazu im Ordner src/controls/PropertyPaneAsyncDropdown/components eine neue Datei mit dem Namen IAsyncDropdownProps.ts, und geben Sie folgenden Code in die Datei ein:
import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; export interface IAsyncDropdownProps { label: string; loadOptions: () => Promise<IDropdownOption[]>; onChanged: (option: IDropdownOption, index?: number) => void; selectedKey: string | number; disabled: boolean; stateKey: string; }
Die Klasse
IAsyncDropdownProps
definiert Eigenschaften, die für die React-Komponente festgelegt werden können, die vom benutzerdefinierten Steuerelement im Eigenschaftenbereich verwendet wird:- Die Eigenschaft
label
legt die Beschriftung des Dropdown-Steuerelements fest. - Die mit dem Delegat
loadOptions
verknüpfte Funktion wird vom Steuerelement aufgerufen, um die verfügbaren Optionen zu laden. - Die mit dem Delegat
onChanged
verknüpfte Funktion wird aufgerufen, sobald der Benutzer eine Option aus dem Dropdown auswählt. - Die Eigenschaft
selectedKey
gibt den ausgewählten Wert an. Dabei kann es sich um eine Zeichenfolge oder eine Zahl handeln. - Die Eigenschaft
disabled
gibt an, ob das Dropdown-Steuerelement deaktiviert ist. - Die Eigenschaft
stateKey
wird verwendet, um ein Neurendern der React-Komponente zu erzwingen.
- Die Eigenschaft
Definieren Sie die Schnittstelle der asynchronen React-basierten Dropdownkomponente. Erstellen Sie hierzu im Ordner src/controls/PropertyPaneAsyncDropdown/components eine neue Datei mit dem Namen IAsyncDropdownState.ts, und geben Sie den folgenden Code in die Datei ein:
import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; export interface IAsyncDropdownState { loading: boolean; options: IDropdownOption[]; error: string; }
Die Schnittstelle
IAsyncDropdownState
beschreibt den Status der React-Komponente:- Die Eigenschaft
loading
gibt an, ob die Komponente ihre Optionen gerade lädt. - Die Eigenschaft
options
enthält alle verfügbaren Optionen. - Tritt ein Fehler auf, wird sie der Eigenschaft
error
zugewiesen und von dort an den Benutzer kommuniziert.
- Die Eigenschaft
Definieren Sie die asynchrone React-basierte Dropdownkomponente. Erstellen Sie hierzu im Ordner src/controls/PropertyPaneAsyncDropdown/components eine neue Datei mit dem Namen AsyncDropdown.tsx, und geben Sie folgenden Code in die Datei ein:
import * as React from 'react'; import { Dropdown, IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; import { Spinner } from 'office-ui-fabric-react/lib/components/Spinner'; import { IAsyncDropdownProps } from './IAsyncDropdownProps'; import { IAsyncDropdownState } from './IAsyncDropdownState'; export default class AsyncDropdown extends React.Component<IAsyncDropdownProps, IAsyncDropdownState> { private selectedKey: React.ReactText; constructor(props: IAsyncDropdownProps, state: IAsyncDropdownState) { super(props); this.selectedKey = props.selectedKey; this.state = { loading: false, options: undefined, error: undefined }; } public componentDidMount(): void { this.loadOptions(); } public componentDidUpdate(prevProps: IAsyncDropdownProps, prevState: IAsyncDropdownState): void { if (this.props.disabled !== prevProps.disabled || this.props.stateKey !== prevProps.stateKey) { this.loadOptions(); } } private loadOptions(): void { this.setState({ loading: true, error: undefined, options: undefined }); this.props.loadOptions() .then((options: IDropdownOption[]): void => { this.setState({ loading: false, error: undefined, options: options }); }, (error: any): void => { this.setState((prevState: IAsyncDropdownState, props: IAsyncDropdownProps): IAsyncDropdownState => { prevState.loading = false; prevState.error = error; return prevState; }); }); } public render(): JSX.Element { const loading: JSX.Element = this.state.loading ? <div><Spinner label={'Loading options...'} /></div> : <div />; const error: JSX.Element = this.state.error !== undefined ? <div className={'ms-TextField-errorMessage ms-u-slideDownIn20'}>Error while loading items: {this.state.error}</div> : <div />; return ( <div> <Dropdown label={this.props.label} disabled={this.props.disabled || this.state.loading || this.state.error !== undefined} onChanged={this.onChanged.bind(this)} selectedKey={this.selectedKey} options={this.state.options} /> {loading} {error} </div> ); } private onChanged(option: IDropdownOption, index?: number): void { this.selectedKey = option.key; // reset previously selected options const options: IDropdownOption[] = this.state.options; options.forEach((o: IDropdownOption): void => { if (o.key !== option.key) { o.selected = false; } }); this.setState((prevState: IAsyncDropdownState, props: IAsyncDropdownProps): IAsyncDropdownState => { prevState.options = options; return prevState; }); if (this.props.onChanged) { this.props.onChanged(option, index); } } }
Die Klasse
AsyncDropdown
stellt die React-Komponente dar, die verwendet wird, um das asynchrone Dropdown-Steuerelement im Eigenschaftenbereich zu rendern:- Wenn die Komponente zum ersten Mal geladen wird, ändert sich die Methode
componentDidMount()
, oder es ändern sich ihre Eigenschaftendisabled
oderstateKey
. Anschließend werden durch Aufrufen der über die Eigenschaften übergebenen MethodeloadOptions()
die verfügbaren Optionen geladen. - Sobald die Optionen geladen wurden, wird der Status der Komponente aktualisiert, und die verfügbaren Optionen werden angezeigt.
- Das Dropdown selbst wird mithilfe der Office UI Fabric React-Dropdownkomponente gerendert.
- Während die Komponente die verfügbaren Optionen lädt, wird mithilfe der Office UI Fabric React-Drehfeldkomponente ein Drehfeld angezeigt.
- Wenn die Komponente zum ersten Mal geladen wird, ändert sich die Methode
Der nächste Schritt besteht darin, das benutzerdefinierte Steuerelement für den Eigenschaftenbereich zu definieren. Dieses Steuerelement wird im Webpart zum Definieren von Eigenschaften im Eigenschaftenbereich verwendet und mithilfe der zuvor definierten React-Komponente gerendert.
Hinzufügen eines asynchronen Dropdown-Steuerelements zum Eigenschaftenbereich
Definieren Sie die Eigenschaften des asynchronen Dropdown-Steuerelements für den Eigenschaftenbereich. Ein benutzerdefiniertes Eigenschaftenbereich-Steuerelement weist zwei Eigenschaftensätze auf.
Der erste Satz von Eigenschaften wird öffentlich verfügbar gemacht und wird zum Definieren der Webparteigenschaft innerhalb des Webparts verwendet. Diese Eigenschaften sind komponentenspezifische Eigenschaften wie beispielsweise die Bezeichnung, die neben dem Steuerelement angezeigt wird, Mindest- und Maximalwerte für ein Drehfeld oder verfügbare Optionen für ein Dropdown. Bei der Definition eines benutzerdefinierten Eigenschaftenbereich-Steuerelements muss der Typ, der diese Eigenschaften beschreibt, als Typ
TProperties
übergeben werden, wenn dieIPropertyPaneField<TProperties>
-Schnittstelle implementiert wird.Bei dem zweiten Satz von Eigenschaften handelt es sich um private Eigenschaften, die intern innerhalb des benutzerdefinierten Eigenschaftenbereichssteuerelements verwendet werden. Diese Eigenschaften müssen den SharePoint Framwork-APIs entsprechen, damit das benutzerdefinierte Steuerelement korrekt gerendert wird. Diese Eigenschaften müssen die
IPropertyPaneCustomFieldProps
Schnittstelle aus dem paket @microsoft/sp-property-pane implementieren.Definieren Sie die öffentlichen Eigenschaften des asynchronen Dropdown-Steuerelements für den Eigenschaftenbereich. Erstellen Sie hierzu im Ordner src/controls/PropertyPaneAsyncDropdown eine neue Datei mit dem Namen IPropertyPaneAsyncDropdownProps.ts, und geben Sie den folgenden Code in die Datei ein:
import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; export interface IPropertyPaneAsyncDropdownProps { label: string; loadOptions: () => Promise<IDropdownOption[]>; onPropertyChange: (propertyPath: string, newValue: any) => void; selectedKey: string | number; disabled?: boolean; }
Folgendes gilt in der
IPropertyPaneAsyncDropdownProps
-Schnittstelle:-
label
: Definiert die Bezeichnung, die neben dem Dropdown angezeigt wird. -
loadOptions
: Definiert die Methode, die zum Laden der verfügbaren Dropdownoptionen aufgerufen wird. -
onPropertyChange
: Definiert eine Methode, die aufgerufen wird, wenn der Benutzer einen Wert aus dem Dropdown auswählt. -
selectedKey
: Gibt den aus dem Dropdown ausgewählten Wert zurück. -
disabled
: Gibt an, ob das Steuerelement deaktiviert ist.
-
Definieren Sie die internen Eigenschaften des asynchronen Dropdown-Steuerelements für den Eigenschaftenbereich. Erstellen Sie hierzu im Ordner src/controls/PropertyPaneAsyncDropdown eine neue Datei mit dem Namen IPropertyPaneAsyncDropdownInternalProps.ts, und geben Sie den folgenden Code in die Datei ein:
import { IPropertyPaneCustomFieldProps } from '@microsoft/sp-property-pane'; import { IPropertyPaneAsyncDropdownProps } from './IPropertyPaneAsyncDropdownProps'; export interface IPropertyPaneAsyncDropdownInternalProps extends IPropertyPaneAsyncDropdownProps, IPropertyPaneCustomFieldProps { }
Die IPropertyPaneAsyncDropdownInternalProps
-Schnittstelle definiert zwar keine neuen Eigenschaften, kombiniert aber die Eigenschaften aus der zuvor definierten IPropertyPaneAsyncDropdownProps
-Schnittstelle und der SharePoint-Framework-Standardschnittstelle IPropertyPaneCustomFieldProps
. Diese ist erforderlich, damit ein benutzerdefiniertes Steuerelement korrekt ausgeführt wird.
Definieren Sie das asynchrone Dropdown-Steuerelement für den Eigenschaftenbereich. Erstellen Sie hierzu im Ordner src/controls/PropertyPaneAsyncDropdown eine neue Datei mit dem Namen PropertyPaneAsyncDropdown.ts, und geben Sie den folgenden Code in die Datei ein:
import * as React from 'react'; import * as ReactDom from 'react-dom'; import { IPropertyPaneField, PropertyPaneFieldType } from '@microsoft/sp-property-pane'; import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; import { IPropertyPaneAsyncDropdownProps } from './IPropertyPaneAsyncDropdownProps'; import { IPropertyPaneAsyncDropdownInternalProps } from './IPropertyPaneAsyncDropdownInternalProps'; import AsyncDropdown from './components/AsyncDropdown'; import { IAsyncDropdownProps } from './components/IAsyncDropdownProps'; export class PropertyPaneAsyncDropdown implements IPropertyPaneField<IPropertyPaneAsyncDropdownProps> { public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom; public targetProperty: string; public properties: IPropertyPaneAsyncDropdownInternalProps; private elem: HTMLElement; constructor(targetProperty: string, properties: IPropertyPaneAsyncDropdownProps) { this.targetProperty = targetProperty; this.properties = { key: properties.label, label: properties.label, loadOptions: properties.loadOptions, onPropertyChange: properties.onPropertyChange, selectedKey: properties.selectedKey, disabled: properties.disabled, onRender: this.onRender.bind(this), onDispose: this.onDispose.bind(this) }; } public render(): void { if (!this.elem) { return; } this.onRender(this.elem); } private onDispose(element: HTMLElement): void { ReactDom.unmountComponentAtNode(element); } private onRender(elem: HTMLElement): void { if (!this.elem) { this.elem = elem; } const element: React.ReactElement<IAsyncDropdownProps> = React.createElement(AsyncDropdown, { label: this.properties.label, loadOptions: this.properties.loadOptions, onChanged: this.onChanged.bind(this), selectedKey: this.properties.selectedKey, disabled: this.properties.disabled, // required to allow the component to be re-rendered by calling this.render() externally stateKey: new Date().toString() }); ReactDom.render(element, elem); } private onChanged(option: IDropdownOption, index?: number): void { this.properties.onPropertyChange(this.targetProperty, option.key); } }
Die Klasse
PropertyPaneAsyncDropdown
implementiert die SharePoint-Framework-StandardschnittstelleIPropertyPaneField
, unter Verwendung derIPropertyPaneAsyncDropdownProps
-Schnittstelle als Vertrag für die öffentlichen Eigenschaften, die innerhalb des Webparts festgelegt werden können. Die Klasse enthält die folgenden drei öffentlichen Eigenschaften, die von der SchnittstelleIPropertyPaneField
definiert werden:-
type
: Muss für ein benutzerdefiniertes Eigenschaftenbereich-Steuerelement aufPropertyPaneFieldType.Custom
festgelegt werden. -
targetProperty
: Wird zum Angeben des Namens der Webparteigenschaft verwendet, die mit dem Steuerelement verwendet werden soll. -
properties
: Wird zum Definieren von steuerelementspezifischen Eigenschaften verwendet.
Beachten Sie, dass die
properties
-Eigenschaft vom internenIPropertyPaneAsyncDropdownInternalProps
-Typ ist und nicht von der öffentlichenIPropertyPaneAsyncDropdownProps
-Schnittstelle, die von der Klasse implementiert wird. Dies ist gewollt, damit die Eigenschaftproperties
die MethodeonRender()
definieren kann, die vom SharePoint-Framework gefordert wird. Wäre die MethodeonRender()
Teil der öffentlichenIPropertyPaneAsyncDropdownProps
-Schnittstelle, müssten Sie ihr bei Verwendung des asynchronen Dropdown-Steuerelements im Webpart einen Wert zuweisen. Das ist nicht erstrebenswert.Die Klasse
PropertyPaneAsyncDropdown
definiert eine öffentlicherender()
-Methode, die zum Aktualisieren des Steuerelements verwendet werden kann. Das ist beispielsweise bei kaskadierenden Dropdowns nützlich, bei denen ein in Dropdown 1 festgelegter Wert festlegt, welche Optionen in Dropdown 2 verfügbar sind. Durch Aufrufen der Methoderender()
nach dem Auswählen eines Elements können die verfügbaren Optionen vom abhängigen Dropdown geladen werden. Hierfür muss React erkennen können, dass sich das Steuerelement geändert hat. Das ermöglichen Sie durch Festlegen des Werts vonstateKey
auf das jeweils aktuelle Datum. Mithilfe dieses Tricks wird bei jedem Aufruf der MethodeonRender()
die Komponente nicht nur erneut gerendert, sondern es werden auch ihre verfügbaren Optionen aktualisiert. Vergessen Sie nicht, die MethodeonDispose()
zu implementieren, um das Element jedes Mal aufzuheben, wenn Sie den Eigenschaftenbereich schließen.-
Verwenden des asynchronen Dropdown-Steuerelements für den Eigenschaftenbereich im Webpart
Sobald das asynchrone Dropdown-Steuerelement für den Eigenschaftenbereich bereit ist, besteht der nächste Schritt darin, es innerhalb des Webparts zu verwenden, damit Benutzer eine Liste auswählen können.
Hinzufügen einer Schnittstelle des Typs „ListInfo“
Um Informationen zu verfügbaren Listen auf konsistente Art und Weise zu übergeben, definieren Sie eine Schnittstelle, die Informationen zu einer Liste darstellt. Erstellen Sie hierzu im Ordner src/webparts/listItems eine neue Datei mit dem Namen IListInfo.ts , und geben Sie den folgenden Code in die Datei ein:
export interface IListInfo {
Id: string;
Title: string;
}
Verwenden des asynchronen Dropdown-Steuerelements für den Eigenschaftenbereich zum Rendern der Webparteigenschaft „listName“
Referenzieren Sie die erforderlichen Typen. Importieren Sie hierzu im oberen Teil der Datei src/webparts/listItems/ListItemsWebPart.ts die zuvor erstellte Klasse
PropertyPaneAsyncDropdown
, indem Sie folgenden Code hinzufügen:import { PropertyPaneAsyncDropdown } from '../../controls/PropertyPaneAsyncDropdown/PropertyPaneAsyncDropdown';
Fügen Sie unter diesem Code einen Verweis auf die Schnittstelle
IDropdownOption
und zwei Hilfsfunktionen hinzu, die für die Arbeit mit Webparteigenschaften erforderlich sind.import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; import { update, get } from '@microsoft/sp-lodash-subset';
Hinzufügen einer Methode zum Laden von verfügbaren Listen. Fügen Sie in der
ListItemsWebPart
-Klasse die folgendeloadLists()
-Methode hinzu, um die verfügbaren Listen zu laden. In diesem Artikel verwenden Sie simulierte Daten; Sie können aber auch die SharePoint-REST-API aufrufen, um die Liste der verfügbaren Listen aus dem aktuellen Web abzurufen. Um Ladeoptionen aus einem externen Dienst zu simulieren, verwendet die Methode eine Verzögerung von zwei Sekunden.private loadLists(): Promise<IDropdownOption[]> { return new Promise<IDropdownOption[]>((resolve: (options: IDropdownOption[]) => void, reject: (error: any) => void) => { setTimeout(() => { resolve([{ key: 'sharedDocuments', text: 'Shared Documents' }, { key: 'myDocuments', text: 'My Documents' }]); }, 2000); }); }
Fügen Sie eine Methode hinzu, die Wertänderungen im Dropdown verarbeitet. Fügen Sie in der
ListItemsWebPart
-Klasse eine neue Methode mit dem NamenonListChange()
hinzu.private onListChange(propertyPath: string, newValue: any): void { const oldValue: any = get(this.properties, propertyPath); // store new value in web part properties update(this.properties, propertyPath, (): any => { return newValue; }); // refresh web part this.render(); }
Nach dem Auswählen einer Liste aus dem Listendropdown sollte der ausgewählte Wert in Webparteigenschaften beibehalten werden, und das Webpart sollte erneut gerendert werden, damit die ausgewählte Eigenschaft übernommen wird.
Rendern Sie die Webparteigenschaft „listName“ mithilfe des asynchronen Dropdown-Steuerelements für den Eigenschaftenbereich. Ändern Sie in der Klasse
ListItemsWebPart
die MethodegetPropertyPaneConfiguration()
so ab, dass sie das asynchrone Dropdown-Steuerelement für den Eigenschaftenbereich zum Rendern der WebparteigenschaftlistName
verwendet.export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { return { pages: [ { header: { description: strings.PropertyPaneDescription }, groups: [ { groupName: strings.BasicGroupName, groupFields: [ new PropertyPaneAsyncDropdown('listName', { label: strings.ListFieldLabel, loadOptions: this.loadLists.bind(this), onPropertyChange: this.onListChange.bind(this), selectedKey: this.properties.listName }) ] } ] } ] }; } // ... }
An diesem Punkt können Sie eine Liste mithilfe des neu erstellten asynchronen Dropdown-Eigenschaftenbereichs-Steuerelements auswählen. Um zu überprüfen, ob das Steuerelement wie erwartet funktioniert, öffnen Sie die Konsole, und führen Sie Folgendes aus:
gulp serve
Implementieren kaskadierender Dropdowns mithilfe des asynchronen Dropdown-Steuerelements für Eigenschaftenbereiche
Beim Erstellen von SharePoint-Framework-Webparts müssen Sie möglicherweise eine Konfiguration implementieren, bei der es von einer anderen zuvor ausgewählten Option abhängt, welche Optionen verfügbar sind. Ein typisches Beispiel besteht darin, Benutzer zuerst eine Liste und dann ein Listenelement aus dieser Liste auswählen zu lassen. Die Liste der verfügbaren Element wäre von der ausgewählten Liste abhängig. Nachfolgend erfahren Sie, wie ein solches Szenario mithilfe des in den vorangegangenen Abschnitten implementieren asynchronen Dropdown-Steuerelements für den Eigenschaftbereich umgesetzt werden kann.
Hinzufügen der Webparteigenschaft „item“
Öffnen Sie im Code-Editor die Datei src/webparts/listItems/ListItemsWebPart.manifest.json. Fügen Sie im
properties
-Abschnitt eine neue Eigenschaft namens "item
" hinzu. Der Code sollte wie folgt aussehen:{ ... "preconfiguredEntries": [{ ... "properties": { "description": "List items", "listName": "", "item": "" } }] }
Ändern Sie den Code in der IListItemsWebPartProps-Schnittstelle in der Datei src/webparts/listItems/ListItemsWebPart.ts wie folgt:
export interface IListItemsWebPartProps { description: string; listName: string; item: string; }
Aktualisieren Sie den Inhalt der Datei src/webparts/listItems/components/IListItemsProps.ts, um die
item
Eigenschaft hinzuzufügen:export interface IListItemsProps { ... listName: string; itemName: string; }
Ändern Sie in der Datei src/webparts/listItems/ListItemsWebPart.ts den Code der
render()
-Methode, um dieitem
Eigenschaft aufzunehmen:export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... public render(): void { const element: React.ReactElement<IListItemsProps> = React.createElement(ListItems, { listName: this.properties.listName, itemName: this.properties.item, ... }); ReactDom.render(element, this.domElement); } // ... }
Ändern Sie in der Datei src/webparts/listItems/loc/mystrings.d.ts die
IListItemsWebPartStrings
Schnittstelle, um dieItemFieldLabel
Eigenschaft aufzunehmen:declare interface IListItemsWebPartStrings { ... PropertyPaneDescription: string; BasicGroupName: string; ListFieldLabel: string; ItemFieldLabel: string; }
Fügen Sie in der Datei src/webparts/listItems/loc/en-us.js die fehlende Definition für die Zeichenfolge
ItemFieldLabel
hinzu:define([], function() { return { ... "PropertyPaneDescription": "Description", "BasicGroupName": "Group Name", "ListFieldLabel": "List", "ItemFieldLabel": "Item" } });
Rendern des Werts der Webparteigenschaft „item“
Ändern Sie in der Datei src/webparts/listItems/components/ListItems.tsx die render()
-Methode wie folgt:
export default class ListItems extends React.Component<IListItemsProps, {}> {
public render(): React.ReactElement<IListItemsProps> {
const {
description,
isDarkTheme,
environmentMessage,
hasTeamsContext,
userDisplayName,
listName,
itemName
} = this.props;
return (
<section className={`${styles.listItems} ${hasTeamsContext ? styles.teams : ''}`}>
<div className={styles.welcome}>
<img alt="" src={isDarkTheme ? require('../assets/welcome-dark.png') : require('../assets/welcome-light.png')} className={styles.welcomeImage} />
<h2>Well done, {escape(userDisplayName)}!</h2>
<div>{environmentMessage}</div>
<div>List name: <strong>{escape(listName)}</strong></div>
<div>Item name: <strong>{escape(itemName)}</strong></div>
</div>
</section>
);
}
}
Hinzufügen einer Methode zum Laden von Listenelementen
Fügen Sie in der Datei src/webparts/listItems/ListItemsWebPart.ts in der ListItemsWebPart
-Klasse eine neue Methode zum Laden der verfügbaren Listenelemente aus der ausgewählten Liste hinzu. Wie auch bei der Methode zum Laden der verfügbaren Listen verwenden Sie hier simulierte Daten. In Abhängigkeit von der zuvor ausgewählten Liste gibt die loadItems()
-Methode simulierte Listenelemente zurück. Wenn keine Liste ausgewählt wurde, löst die Methode die Zusage ohne Daten.
private loadItems(): Promise<IDropdownOption[]> {
if (!this.properties.listName) {
// resolve to empty options since no list has been selected
return Promise.resolve([]);
}
const wp: ListItemsWebPart = this;
return new Promise<IDropdownOption[]>((resolve: (options: IDropdownOption[]) => void, reject: (error: any) => void) => {
setTimeout(() => {
const items = {
sharedDocuments: [
{
key: 'spfx_presentation.pptx',
text: 'SPFx for the masses'
},
{
key: 'hello-world.spapp',
text: 'hello-world.spapp'
}
],
myDocuments: [
{
key: 'isaiah_cv.docx',
text: 'Isaiah CV'
},
{
key: 'isaiah_expenses.xlsx',
text: 'Isaiah Expenses'
}
]
};
resolve(items[wp.properties.listName]);
}, 2000);
});
}
Hinzufügen einer Methode zum Verarbeiten der Auswahl eines Elements
Fügen Sie in der ListItemsWebPart
-Klasse eine neue Methode mit dem NamenonListItemChange()
hinzu. Nach Auswahl eines Elements in der Element-Dropdownliste sollte das Webpart den neuen Wert in den Webparteigenschaften speichern und das Webpart erneut rendern, um die Änderungen in der Benutzeroberfläche widerzuspiegeln.
private onListItemChange(propertyPath: string, newValue: any): void {
const oldValue: any = get(this.properties, propertyPath);
// store new value in web part properties
update(this.properties, propertyPath, (): any => { return newValue; });
// refresh web part
this.render();
}
Rendern der Webparteigenschaft „item“ im Eigenschaftenbereich
Fügen Sie in der
ListItemsWebPart
-Klasse eine neue Klasseneigenschaft namensitemsDropdown
hinzu:export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { private itemsDropDown: PropertyPaneAsyncDropdown; // ... }
Ändern Sie den Code der
getPropertyPaneConfiguration()
-Methode wie folgt:export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration { // reference to item dropdown needed later after selecting a list this.itemsDropDown = new PropertyPaneAsyncDropdown('item', { label: strings.ItemFieldLabel, loadOptions: this.loadItems.bind(this), onPropertyChange: this.onListItemChange.bind(this), selectedKey: this.properties.item, // should be disabled if no list has been selected disabled: !this.properties.listName }); return { pages: [ { header: { description: strings.PropertyPaneDescription }, groups: [ { groupName: strings.BasicGroupName, groupFields: [ new PropertyPaneAsyncDropdown('listName', { label: strings.ListFieldLabel, loadOptions: this.loadLists.bind(this), onPropertyChange: this.onListChange.bind(this), selectedKey: this.properties.listName }), this.itemsDropDown ] } ] } ] }; } // ... }
Das Dropdown für die Eigenschaft „item“ wird ähnlich wie das Dropdown für die Eigenschaft „listName“ initialisiert. Der einzige Unterschied besteht darin, dass eine Instanz des Steuerelements der Klassenvariablen zugewiesen werden muss, da nach dem Auswählen einer Liste das Elementdropdown aktualisiert werden muss.
Laden von Elementen aus der ausgewählten Liste
Zu Beginn, wenn keine Liste ausgewählt ist, ist das Elementdropdown deaktiviert; es wird aktiviert, sobald der Benutzer eine Liste auswählt. Nachdem eine Liste ausgewählt wurde, lädt das Elementdropdown auch die Listenelemente dieser Liste.
Um diese Logik zu implementieren, erweitern Sie die zuvor definierte Methode
onListChange()
wie folgt:private onListChange(propertyPath: string, newValue: any): void { const oldValue: any = get(this.properties, propertyPath); // store new value in web part properties update(this.properties, propertyPath, (): any => { return newValue; }); // reset selected item this.properties.item = undefined; // store new value in web part properties update(this.properties, 'item', (): any => { return this.properties.item; }); // refresh web part this.render(); // reset selected values in item dropdown this.itemsDropDown.properties.selectedKey = this.properties.item; // allow to load items this.itemsDropDown.properties.disabled = false; // load items and re-render items dropdown this.itemsDropDown.render(); }
Nach dem Auswählen einer Liste wird das ausgewählte Element zurückgesetzt, in den Webparteigenschaften beibehalten und in der Element-Dropdownliste zurückgesetzt. Die Dropdownliste zum Auswählen eines Elements wird aktiviert, und die Dropdownliste wird aktualisiert, um ihre Optionen zu laden.
Führen Sie über die Konsole folgenden Befehl aus, um zu überprüfen, ob alles wie erwartet funktioniert:
gulp serve
Nachdem Sie das Webpart das erste Mal zu der Seite hinzugefügt und seinen Eigenschaftenbereich geöffnet haben, sollten Sie beide Dropdownlisten deaktiviert und beim Laden ihrer Optionen sehen.
Nachdem die Optionen geladen wurden, wird die Dropdownliste aktiviert. Da noch keine Liste ausgewählt wurde, bleibt die Dropdownliste deaktiviert.
Nach dem Auswählen einer Liste in der Dropdownliste werden die in dieser Liste verfügbaren Elemente geladen.
Nachdem die verfügbaren Elemente geladen wurden, wird die Element-Dropdownliste aktiviert.
Nach dem Auswählen eines Elements in der Element-Dropdownliste wird das Webpart aktualisiert und zeigt das ausgewählte Element im Text an.
Beenden Sie den lokalen Webserver, indem Sie in der Konsole STRG+C drücken.