Création de contrôles personnalisés pour le volet de propriétés
Le SharePoint Framework contient un ensemble de contrôles standard pour le volet des propriétés. Mais parfois, vous avez besoin de fonctionnalités supplémentaires au-delà des contrôles de base. Vous pouvez avoir besoin de mises à jour asynchrones des données d'un contrôle ou d'une interface utilisateur spécifique. Créez un contrôle personnalisé pour le volet des propriétés afin d'obtenir la fonctionnalité dont vous avez besoin.
Dans cet article, vous allez construire un contrôle de liste déroulante personnalisé qui charge ses données de manière asynchrone à partir d'un service externe sans bloquer l'interface utilisateur du composant Web.

La source du composant WebPart de travail est disponible sur GitHub à l’adresse sp-dev-fx-webparts/samples/react-custompropertypanecontrols/.
Notes
Avant de suivre la procédure décrite dans cet article, n’oubliez pas de configurer votre environnement de développement pour générer des solutions SharePoint Framework.
Création d’un projet
Commencez par créer un dossier pour votre projet :
md react-custompropertypanecontrolAccédez au dossier du projet :
cd react-custompropertypanecontrolDans le dossier du projet, exécutez le générateur Yeoman pour SharePoint Framework afin de structurer un projet SharePoint Framework :
yo @microsoft/sharepointLorsque vous y êtes invité, entrez les valeurs suivantes (sélectionnez l’option par défaut pour toutes les invites omises ci-dessous) :
- Quel est le nom de votre solution ? react-custompropertypanecontrol
- Quels packages de base voulez-vous cibler pour votre ou vos composant(s) ? SharePoint Online uniquement (dernière version)
- Où voulez-vous placer les fichiers ? : utilisez le dossier actuel
- Quel type de composant côté client voulez-vous créer? Composant WebPart
- Quel est le nom de votre composant WebPart ? Éléments de la liste
- Quelle est la description de votre composant WebPart ? affiche les éléments de la liste de la liste sélectionnée
- Quelle infrastructure voulez-vous utiliser ? : React
Ouvrez votre dossier de projet dans votre éditeur de code. Cet article utilise Visual Studio Code dans les étapes et les captures d'écran, mais vous pouvez utiliser l'éditeur que vous préférez.
Définir la propriété du composant WebPart pour stocker la liste sélectionnée
Le composant Web que vous créez affiche les éléments de la liste SharePoint sélectionnée. Les utilisateurs peuvent sélectionner une liste dans les propriétés du composant Web. Pour stocker la liste sélectionnée, créez une propriété pour le composant WebPart intitulée listName.
Dans l’éditeur de code, ouvrez le fichier src/webparts/listItems/ListItemsWebPartManifest.json. Remplacez la propriété
descriptionpar défaut par une nouvelle propriété nomméelistName.{ ... "preconfiguredEntries": [{ ... "properties": { "listName": "" } }] }Ouvrez le fichier src/webparts/listItems/IListItemsWebPartProps.ts et remplacez son contenu par ce qui suit :
export interface IListItemsWebPartProps { listName: string; }Dans le fichier src/webparts/listItems/ListItemsWebPart.ts, remplacez la méthode
render()par :export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... public render(): void { const element: React.ReactElement<IListItemsProps> = React.createElement(ListItems, { listName: this.properties.listName }); ReactDom.render(element, this.domElement); } // ... }Mettez à jour la méthode
getPropertyPaneConfiguration()de la façon suivante :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 }) ] } ] } ] }; } // ... }Dans le fichier src/webparts/listItems/loc/mystrings.d.ts, remplacez l’interface
IListItemsWebPartStringspar :declare interface IListItemsWebPartStrings { PropertyPaneDescription: string; BasicGroupName: string; ListFieldLabel: string; }Dans le fichier src/webparts/listItems/loc/en-us.js, ajoutez la définition manquante pour la chaîne
ListFieldLabel.define([], function() { return { "PropertyPaneDescription": "Description", "BasicGroupName": "Group Name", "ListFieldLabel": "List" } });Dans le fichier src/webparts/listItems/components/ListItems.tsx, remplacez le contenu de la méthode
render()par :export default class ListItems extends React.Component<IListItemsProps, {}> { public render(): React.ReactElement<IListItemsProps> { return ( <div className={styles.listItems}> <div className={styles.container}> <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}> <div className="ms-Grid-col ms-lg10 ms-xl8 ms-xlPush2 ms-lgPush1"> <span className="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span> <p className="ms-font-l ms-fontColor-white">Customize SharePoint experiences using web parts.</p> <p className="ms-font-l ms-fontColor-white">{escape(this.props.listName)}</p> <a href="https://aka.ms/spfx" className={styles.button}> <span className={styles.label}>Learn more</span> </a> </div> </div> </div> </div> ); } }Ouvrez le fichier src/webparts/listItems/components/IListItemsProps.ts et remplacez son contenu par :
export interface IListItemsProps { listName: string; }Exécutez la commande suivante pour vérifier l’exécution du projet :
gulp serveDans le navigateur web, ajoutez le composant WebPart Éléments de liste dans la zone, puis ouvrez ses propriétés. Vérifiez que la valeur définie pour la propriété Liste s’affiche dans le corps du composant WebPart.

Création d’un contrôle de liste déroulante asynchrone pour le volet de propriétés
Le SharePoint Framework vous offre un contrôle de liste déroulante standard qui permet aux utilisateurs de sélectionner une valeur spécifique. Le contrôle de liste déroulante est conçu de manière à ce que toutes ses valeurs soient connues à l'avance. Si vous souhaitez charger les valeurs de manière dynamique ou si vous chargez les valeurs de manière asynchrone à partir d'un service externe et que vous ne voulez pas bloquer l'ensemble de la partie Web, vous pouvez créer un contrôle de liste déroulante personnalisé.
Lorsque vous créez un contrôle de volet de propriétés personnalisé qui utilise React dans SharePoint Framework, le contrôle comprend une classe qui enregistre le contrôle avec le composant WebPart, et un composant qui affiche la liste déroulante et gère ses données.
Ajout d’un composant React dans le contrôle de liste déroulante asynchrone du volet de propriétés
Créez le dossier « components ». Dans le dossier src du projet, créez une hiérarchie de trois nouveaux dossiers pour que la structure de vos dossiers se présente sous la forme suivante : src/controls/PropertyPaneAsyncDropdown/components.

Définissez les propriétés du composant React de liste déroulante asynchrone. Dans le dossier src/controls/PropertyPaneAsyncDropdown/components, créez un fichier nommé IAsyncDropdownProps.ts, puis entrez le code suivant :
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; }La classe
IAsyncDropdownPropsdéfinit les propriétés pouvant être définies sur le composant React utilisé par le contrôle du volet de propriétés personnalisé :- La propriété
labelindique le nom du contrôle de liste déroulante. - La fonction associée au délégué
loadOptionsest appelée par le contrôle pour charger les options disponibles. - La fonction associée au délégué
onChangedest appelée lorsque l’utilisateur sélectionne une option dans la liste déroulante. - La propriété
selectedKeyindique la valeur sélectionnée (chaîne de caractères ou nombre). - La propriété
disabledindique si le contrôle de liste déroulante est désactivé. - La propriété
stateKeyest utilisée pour forcer le composant React à se réinitialiser.
- La propriété
Définissez l’interface du composant React de liste déroulante asynchrone. Dans le dossier src/controls/PropertyPaneAsyncDropdown/components, créez un fichier nommé IAsyncDropdownState.ts, puis entrez le code suivant :
import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; export interface IAsyncDropdownState { loading: boolean; options: IDropdownOption[]; error: string; }L’interface
IAsyncDropdownStatedécrit l’état du composant React :- La propriété
loadingindique si le composant charge ses options en ce moment. - La propriété
optionscontient toutes les options disponibles. - Si une erreur s’est produite, elle est affectée à la propriété
errordepuis l’endroit où elle est communiquée à l’utilisateur.
- La propriété
Définissez le composant React de liste déroulante asynchrone. Dans le dossier src/controls/PropertyPaneAsyncDropdown/components, créez un fichier nommé AsyncDropdown.tsx, puis entrez le code suivant :
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); } } }La classe
AsyncDropdownreprésente le composant React utilisé pour afficher le contrôle de liste déroulante asynchrone du volet de propriétés :- Lorsque le composant se charge pour la première fois, la méthode
componentDidMount(), ou sesdisabledou propriétésstateKey, changent, et il charge les options disponibles en appelant la méthodeloadOptions()passée par les propriétés. - Une fois les options chargées, le composant met à jour son état et affiche les options disponibles.
- La liste déroulante est aussi affichée à l’aide du composant React de liste déroulante de la structure de l’interface utilisateur Office.
- Lorsque le composant charge les options disponibles, il affiche un compteur à l’aide du composant React du bouton fléché de la structure de l’interface utilisateur Office.
- Lorsque le composant se charge pour la première fois, la méthode
L'étape suivante consiste à définir le contrôle du volet de propriété personnalisé. Ce contrôle est utilisé à l'intérieur de la partie web lors de la définition des propriétés dans le volet de propriété, et effectue le rendu en utilisant le composant React précédemment défini.
Ajout d’un contrôle de liste déroulante asynchrone dans le volet de propriétés
Définissez les propriétés du contrôle de liste déroulante asynchrone du volet de propriétés. Un contrôle de volet de propriétés personnalisé possède deux ensembles de propriétés.
Le premier est exposé publiquement et sert à définir la propriété du composant WebPart dans le composant WebPart. Ces propriétés sont des propriétés spécifiques du composant, comme le nom affiché à côté du contrôle, les valeurs minimale et maximale d’un compteur ou les options disponibles d’une liste déroulante. Lorsque vous définissez un contrôle de volet de propriétés personnalisé, vous devez transmettre le type
TPropertiesqui décrit ces propriétés, lors de l’implémentation de l’interfaceIPropertyPaneField<TProperties>.Le second ensemble de propriétés comprend des propriétés privées utilisées en interne à l’intérieur du contrôle de volet de propriétés personnalisé. Ces propriétés doivent respecter les interfaces API de l’infrastructure SharePoint pour que le contrôle personnalisé s’affiche correctement. Ces propriétés doivent mettre en œuvre
IPropertyPaneCustomFieldPropsl'interface du paquet @microsoft/sp-property-pane.Définissez les propriétés publiques du contrôle de liste déroulante asynchrone du volet de propriétés. Dans le dossier src/controls/PropertyPaneAsyncDropdown, créez un fichier nommé IPropertyPaneAsyncDropdownProps.ts, puis entrez le code suivant :
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; }Dans l’interface
IPropertyPaneAsyncDropdownProps:label: définit le nom affiché à côté de la liste déroulante.loadOptions: définit la méthode appelée pour charger les options disponibles de la liste déroulante.onPropertyChange: définit une méthode appelée lorsque l’utilisateur sélectionne une valeur dans la liste déroulante.selectedKey: renvoie la valeur de la liste déroulante sélectionnée.disabled: indique si le contrôle est désactivé.
Définissez les propriétés internes du contrôle de liste déroulante asynchrone du volet de propriétés. Dans le dossier src/controls/PropertyPaneAsyncDropdown, créez un fichier nommé IPropertyPaneAsyncDropdownInternalProps.ts, puis entrez le code suivant :
import { IPropertyPaneCustomFieldProps } from '@microsoft/sp-property-pane'; import { IPropertyPaneAsyncDropdownProps } from './IPropertyPaneAsyncDropdownProps'; export interface IPropertyPaneAsyncDropdownInternalProps extends IPropertyPaneAsyncDropdownProps, IPropertyPaneCustomFieldProps { }
Bien que l'interface IPropertyPaneAsyncDropdownInternalPropsne définisse pas de nouvelles propriétés, elle combine les propriétés de l'interface précédemment définieIPropertyPaneAsyncDropdownProps et de l'interface SharePoint Framework standardIPropertyPaneCustomFieldProps, ce qui est nécessaire pour qu'un contrôle personnalisé fonctionne correctement.
Définissez le contrôle de liste déroulante asynchrone du volet de propriétés. Dans le dossier src/controls/PropertyPaneAsyncDropdown, créez un fichier nommé PropertyPaneAsyncDropdown.ts, puis entrez le code suivant :
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); } }La classe
PropertyPaneAsyncDropdownmet en œuvre l'interface standardIPropertyPaneFieldSharePoint Framework en utilisant l'interfaceIPropertyPaneAsyncDropdownPropscomme un contrat pour ses propriétés publiques qui peuvent être définies à partir de la partie web. Cette classe contient les trois propriétés publiques suivantes, définies par l’interfaceIPropertyPaneField:type: Doit être défini surPropertyPaneFieldType.Custompour un contrôle de volet de propriété personnalisé.targetProperty: permet d’indiquer le nom de la propriété du composant WebPart à utiliser avec le contrôle.properties: permet de définir les propriétés spécifiques au contrôle.
Remarquez comment la propriété
propertiesest du typeIPropertyPaneAsyncDropdownInternalPropsinterne plutôt que de l'interfaceIPropertyPaneAsyncDropdownPropspublique implémentée par la classe. En effet, le but est de permettre à la propriétépropertiesde définir la méthode requise paronRender()SharePoint Framework. Si la méthodeonRender()faisait partie de l’interfaceIPropertyPaneAsyncDropdownPropspublique, vous devriez lui affecter une valeur dans le composant WebPart lors de l’utilisation du contrôle de liste déroulante asynchrone dans le composant WebPart, ce qui n’est pas souhaitable.La classe
PropertyPaneAsyncDropdowndéfinit une méthoderender()publique, qui peut être utilisée pour repeindre le contrôle. Cette méthode est utile dans les listes déroulantes affichées en cascade lorsqu’une valeur définie dans l’une détermine les options disponibles dans l’autre. En appelant la méthoderender()après avoir sélectionné un élément, la liste déroulante dépendante charge les options disponibles. Pour cela, vous devez faire comprendre à React que le contrôle a été modifié en définissant la valeur de la propriétéstateKeysur la date actuelle. Grâce à cette astuce, le composant est réinitialisé et met à jour les options disponibles lorsque la méthodeonRender()est appelée. N’oubliez pas d’implémenter la méthodeonDispose()pour démonter l’élément chaque fois que vous fermez le volet de propriétés.
Utilisation du contrôle de liste déroulante asynchrone du volet de propriétés dans le composant WebPart
Lorsque le contrôle de liste déroulante asynchrone du volet de propriétés est prêt, il ne vous reste plus qu’à l’utiliser dans le composant WebPart pour permettre aux utilisateurs de sélectionner une liste.
Ajouter une interface d’informations pour les listes
Pour transmettre des informations sur les listes disponibles de manière cohérente, définissez une interface qui affiche les informations de la liste. Dans le dossier src/webparts/listItems, créez un fichier nommé IListInfo.ts, puis entrez le code suivant :
export interface IListInfo {
Id: string;
Title: string;
}
Utiliser le contrôle de liste déroulante asynchrone du volet de propriétés pour afficher la propriété du composant WebPart « listName »
Référencez les types requis. Dans la partie supérieure du fichier src/webparts/listItems/ListItemsWebPart.ts, importez la classe
PropertyPaneAsyncDropdowncréée précédemment en ajoutant :import { PropertyPaneAsyncDropdown } from '../../controls/PropertyPaneAsyncDropdown/PropertyPaneAsyncDropdown';À la suite de ce code, ajoutez une référence à l’interface
IDropdownOptionet deux fonctions auxiliaires qui fonctionnent avec les propriétés du composant WebPart.import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown'; import { update, get } from '@microsoft/sp-lodash-subset';Ajoutez une méthode pour charger les listes disponibles. Dans la classe
ListItemsWebPart, ajoutez une méthode pour charger les listes disponibles. Dans cet article, vous utilisez des données fictives, mais vous pourriez également appeler l'API REST SharePoint pour récupérer la liste des listes disponibles sur le Web actuel. Pour simuler le chargement des options à partir d'un service externe, la méthode utilise un délai de deux secondes.export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... 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); }); } // ... }Ajoutez une méthode pour modifier la valeur dans la liste déroulante. Dans la classe
ListItemsWebPart, ajoutez une méthode nomméeonListChange():export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... 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(); } }Lorsqu’une liste est sélectionnée dans la liste déroulante « Liste », la valeur sélectionnée doit se trouver dans les propriétés du composant WebPart et le composant WebPart doit être réinitialisé pour afficher la propriété sélectionnée.
Affichez la propriété du composant WebPart « Liste » à l’aide du contrôle de liste déroulante asynchrone du volet de propriétés. Dans la classe
ListItemsWebPart, modifiez la méthodegetPropertyPaneConfiguration()pour utiliser le contrôle asynchrone du volet de propriété du menu déroulantlistNamepour rendre la propriété de la partie web.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 }) ] } ] } ] }; } // ... }À ce stade, vous pouvez sélectionner une liste en utilisant le contrôle de volet de propriété de liste déroulante asynchrone nouvellement créé. Pour vérifier que le contrôle fonctionne comme prévu, ouvrez la console et exécutez :
gulp serve

Implémentation des listes déroulantes en cascade à l’aide du contrôle de liste déroulante asynchrone du volet de propriétés
Lorsque vous créez des composants Web SharePoint Framework, vous pouvez être amené à mettre en œuvre une configuration dans laquelle les options disponibles dépendent d'une autre option choisie précédemment. Un exemple courant est de laisser les utilisateurs choisir une liste et, à partir de cette liste, sélectionner un élément de liste. La liste des éléments disponibles dépendrait de la liste sélectionnée. Voici comment mettre en œuvre un tel scénario en utilisant le contrôle de volet de propriété de liste déroulante asynchrone mis en œuvre dans les étapes précédentes.
Ajouter la propriété du composant WebPart « Élément »
Dans l’éditeur de code, ouvrez le fichier src/webparts/listItems/ListItemsWebPart.manifest.json. Dans la section
properties, ajoutez une propriété nomméeitempour qu’elle apparaisse de la manière suivante :{ ... "preconfiguredEntries": [{ ... "properties": { "listName": "", "item": "" } }] }Remplacez le code dans le fichier src/webparts/listItems/IListItemsWebPartProps.ts par :
export interface IListItemsWebPartProps { listName: string; item: string; }Remplacez le contenu du fichier src/webparts/listItems/components/IListItemsProps.ts par :
export interface IListItemsProps { listName: string; item: string; }Dans le fichier src/webparts/listItems/ListItemsWebPart.ts, remplacez le code de la méthode
render()par :export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... public render(): void { const element: React.ReactElement<IListItemsProps> = React.createElement(ListItems, { listName: this.properties.listName, item: this.properties.item }); ReactDom.render(element, this.domElement); } // ... }Dans le fichier src/webparts/listItems/loc/mystrings.d.ts, remplacez l’interface
IListItemsWebPartStringspar :declare interface IListItemsWebPartStrings { PropertyPaneDescription: string; BasicGroupName: string; ListFieldLabel: string; ItemFieldLabel: string; }Dans le fichier src/webparts/listItems/loc/en-us.js, ajoutez la définition manquante pour la chaîne
ItemFieldLabel:define([], function() { return { "PropertyPaneDescription": "Description", "BasicGroupName": "Group Name", "ListFieldLabel": "List", "ItemFieldLabel": "Item" } });
Afficher la valeur de la propriété du composant WebPart « Élément »
Dans le fichier src/webparts/listItems/components/ListItems.tsx, remplacez la méthode render() par :
export default class ListItems extends React.Component<IListItemsProps, {}> {
public render(): React.ReactElement<IListItemsProps> {
return (
<div className={styles.listItems}>
<div className={styles.container}>
<div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>
<div className="ms-Grid-col ms-lg10 ms-xl8 ms-xlPush2 ms-lgPush1">
<span className="ms-font-xl ms-fontColor-white">Welcome to SharePoint!</span>
<p className="ms-font-l ms-fontColor-white">Customize SharePoint experiences using web parts.</p>
<p className="ms-font-l ms-fontColor-white">{escape(this.props.listName)}</p>
<p className="ms-font-l ms-fontColor-white">{escape(this.props.item)}</p>
<a href="https://aka.ms/spfx" className={styles.button}>
<span className={styles.label}>Learn more</span>
</a>
</div>
</div>
</div>
</div>
);
}
}
Ajouter la méthode pour charger les éléments de liste
Dans le fichier src/webparts/listItems/ListItemsWebPart.ts, dans la classe ListItemsWebPart, ajoutez une nouvelle méthode pour charger les éléments de liste disponibles à partir de la liste sélectionnée. Comme pour la méthode de chargement des listes disponibles, vous utilisez des données fictives. En fonction de la liste sélectionnée précédemment, la méthode loadItems() renvoie des éléments de liste fictifs. Si aucune liste n’a été sélectionnée, la méthode résout la promesse sans aucune donnée.
export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> {
// ...
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);
});
}
}
Ajoute une méthode pour sélectionner un élément
Dans la classe ListItemsWebPart, ajoutez une méthode nommée onListItemChange() : Après avoir sélectionné un élément dans la liste déroulante des éléments, le composant WebPart doit stocker la nouvelle valeur dans les propriétés du composant WebPart et réinitialiser le composant WebPart pour afficher les modifications apportées à l’interface utilisateur.
export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> {
// ...
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();
}
}
Afficher la propriété du composant WebPart « Élément » dans le volet de propriétés
Dans la classe
ListItemsWebPart, ajoutez une nouvelle propriété de classe appeléeitemsDropdown:export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { private itemsDropDown: PropertyPaneAsyncDropdown; // ... }Remplacez le code de la méthode
getPropertyPaneConfiguration()par :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 ] } ] } ] }; } // ... }La liste déroulante pour la propriété item est initialisée de la même manière que la liste déroulante pour la propriété listName. La seule différence est qu'après avoir sélectionné une liste, la liste déroulante des éléments doit être rafraîchie, une instance du contrôle doit être assignée à la variable de classe.
Charger les éléments de la liste sélectionnée
Au départ, lorsqu'aucune liste n'est sélectionnée, la liste déroulante des éléments est désactivée et devient active lorsque l'utilisateur sélectionne une liste. Après avoir sélectionné une liste, la liste déroulante des éléments charge également les éléments de cette liste.
Pour cela, remplacez la méthode
onListChange()définie précédemment par :export default class ListItemsWebPart extends BaseClientSideWebPart<IListItemsWebPartProps> { // ... 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(); } // ... }Après avoir sélectionné une liste, l'élément sélectionné est réinitialisé, persistant dans les propriétés du composant Web et réinitialisé dans la liste déroulante des éléments. La liste déroulante pour la sélection d'un élément devient active, et la liste déroulante est rafraîchie pour charger ses options.
Pour vérifier que tout fonctionne comme prévu, dans la console, exécutez :
gulp serveLorsque vous ajoutez le composant WebPart à la page pour la première fois et ouvrez le volet de propriétés, les listes déroulantes doivent être désactivées et en train de charger leurs options.

Une fois les options chargées, la liste déroulante « Liste » est activée. Si aucune liste n’est sélectionnée, la liste déroulante « Élément » reste désactivée.

Lorsqu’une liste est sélectionnée dans la liste déroulante « Liste », la liste déroulante « Élément » charge les éléments disponibles dans cette liste.

Une fois les éléments disponibles chargés, la liste déroulante « Élément » est activée.

Lorsqu’un élément est sélectionné dans la liste déroulante « Élément », le composant WebPart est actualisé et l’élément sélectionné est affiché dans le corps du composant.

Arrêtez le serveur web local en appuyant sur Ctrl+C dans la console.