Partager via


Didacticiel : Création d’un composant de champ d’application pilotée par modèle

Dans ce didacticiel, vous allez créer un composant field d′application pilotée par modèle et le déployer, le configurer et le tester dans un formulaire en utilisant Visual Studio Code. Ce composant de code affiche un ensemble de choix sur le formulaire avec une icône à côté de chaque valeur de choix. Le composant utilise certaines des fonctionnalités avancées des applications pilotées par modèle, telles que les définitions de colonnes de choix (métadonnées) et la sécurité au niveau de la colonne.

De plus, veillez aussi à ce que le composant de code respecte les conseils de meilleures pratiques :

  1. Utilisation de Microsoft Fluent UI pour la cohérence et l’accessibilité
  2. Localisation des étiquettes de composant de code à la conception et à l′exécution
  3. Assurance que le composant de code est basé sur les métadonnées pour une meilleure réutilisation
  4. Assurance que le composant de code s′affiche selon le facteur de forme et la largeur disponible, en affichant une liste déroulante compacte avec des icônes là où l′espace est limité

Composant de sélecteur de choix.

Code

Vous pouvez télécharger l’exemple complet ici : PowerApps-Samples/component-framework/ChoicesPickerControl/.

Créer un projet pcfproj

Notes

Avant de commencer, assurez-vous d’avoir installé toutes les conditions préalables.

Pour créer un pcfproj :

  1. Créez le dossier qui contiendra le composant de code. Par exemple, C:\repos\ChoicesPicker

  2. Ouvrez Visual Studio Code et accédez à Fichier > Ouvrir le dossier, puis sélectionnez le dossier ChoicesPicker créé lors de l′étape précédente. Si vous avez ajouté les extensions de l′Explorateur Windows lors de l′installation de Visual Studio Code, vous pouvez aussi utiliser l′option de menu contextuel Ouvrir avec le code dans le dossier. Vous pouvez également ajouter un dossier dans Visual Studio Code utilisant code . dans l′invite de commandes si le répertoire actuel est défini sur cet emplacement.

  3. Dans le nouveau terminal PowerShell Visual Studio Code (Terminal > Nouveau terminal), utilisez la commande pac pcf init pour créer un projet de composant de code :

    pac pcf init `
       --namespace SampleNamespace `
       --name ChoicesPicker `
       --template field `
       --run-npm-install
    

    ou en utilisant la forme courte :

    pac pcf init -ns SampleNamespace -n ChoicesPicker -t field -npm
    

Un nouveau ChoicesPicker.pcfproj et des fichiers associés sont ajoutés au dossier actuel, dont un fichier package.json qui définit les modules obligatoires. La commande ci-dessus exécute également la commande npm install pour que vous installiez les modules obligatoires.

Running 'npm install' for you...

Notes

Si vous affichez l’erreur The term 'npm' is not recognized as the name of a cmdlet, function, script file, or operable program., assurez-vous d’avoir installé node.js (la version LTS est recommandée) et tous les autres conditions préalables.

Création d’un composant de code à l’aide de pac pcf init.

Vous remarquez que le modèle contient un fichier index.ts avec divers fichiers de configuration. Il s’agit du point de départ du composant de code, il contient les méthodes de cycle de vie décrites dans Implémentation des composants.

Installation de Microsoft Fluent UI

Vous allez utiliser Microsoft Fluent UI et React pour créer l′interface utilisateur, vous devez donc les installer en tant que dépendances. Pour installer les dépendances, utilisez :

npm install react react-dom @fluentui/react

Cela ajoute les modules au fichier packages.json et les installe dans le dossier node_modules. Ne validez pas node_modules dans le contrôle de source puisque tous les modules obligatoires seront restaurés à l’aide de npm install.

L’un des avantages de Microsoft Fluent UI est sa capacité à fournir une interface utilisateur cohérente et hautement accessible.

Configuration de eslint

Le modèle utilisé par pac pcf init installe le module eslint sur le projet et le configure en ajoutant un fichier .eslintrc.json. Eslint nécessite une configuration pour les styles de codage TypeScript et React. Plus d’informations : Linting – Meilleures pratiques et conseils pour les composants de code.

Modifier le manifeste

Le fichier ChoicesPicker\ControlManifest.Input.xml définit les métadonnées qui décrivent le comportement du composant de code. Les attributs control contiennent déjà l’espace de noms et le nom du composant.

Vous devez définir les propriétés d’entrée et de sortie suivantes :

Nom  Utilisation Type Description
Value bound OptionSet Cette propriété sera liée à la colonne de choix. Le composant de code reçoit la valeur actuelle, puis notifie le contexte parent lorsque la valeur a changé.
Mappage d’icônes input Plusieurs lignes de texte Cette propriété a sa valeur définie lorsque le créateur d’applications ajoute le composant de code au formulaire. Elle contient une chaîne JSON pour configurer les icônes utilisées pour chaque valeur de choix.

Plus d’informations : élément de propriété.

Conseil

Vous trouverez peut-être le XML plus facile à lire en le formatant de manière à ce que les attributs apparaissent sur des lignes séparées. Trouvez et installez un outil de mise en forme XML de votre choix dans le marketplace Visual Studio Code : Rechercher des extensions de formatage xml.

Les exemples ci-dessous ont été formatés avec des attributs sur des lignes séparées pour les rendre plus faciles à lire.

Remplacer le sampleProperty existant par de nouvelles propriétés

Ouvrez ChoicesPicker\ControlManifest.Input.xml et collez les définitions de propriété suivantes dans l’élément de contrôle (en remplaçant la propriété sampleProperty existante) :

<property name="sampleProperty"
  display-name-key="Property_Display_Key"
  description-key="Property_Desc_Key"
  of-type="SingleLine.Text"
  usage="bound"
  required="true" />

Enregistrez les modifications, puis utilisez la commande suivante pour générer le composant :

npm run build

Une fois le composant généré, vous voyez que :

  • Un fichier ChoicesPicker\generated\ManifestTypes.d.ts généré automatiquement est ajouté au projet. Il est généré lors du processus de génération à partir de ControlManifest.Input.xml et fournit les types d’interaction avec les propriétés d’entrée/sortie.

  • La sortie de version est ajoutée au dossier out. bundle.js est le fichier JavaScript transpilé qui s’exécute dans le navigateur. ControlManifest.xml est une version reformatée du fichier ControlManifest.Input.xml utilisé pendant le déploiement.

    Notes

    Ne modifiez pas le contenu des dossiers generated et out directement. Ils seront remplacés lors du processus de génération.

Mettre en œuvre le composant ChoicesPicker Fluent UI React

Si le composant de code utilise React, un seul composant racine est rendu avec la méthode updateView. Dans le dossier ChoicesPicker, ajoutez un nouveau fichier TypeScript nommé ChoicesPickerComponent.tsx, puis ajoutez le contenu suivant :

import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react/lib/ChoiceGroup';
import * as React from 'react';

export interface ChoicesPickerComponentProps {
    label: string;
    value: number | null;
    options: ComponentFramework.PropertyHelper.OptionMetadata[];
    configuration: string | null;
    onChange: (newValue: number | undefined) => void;
}

export const ChoicesPickerComponent = React.memo((props: ChoicesPickerComponentProps) => {
    const { label, value, options, configuration, onChange } = props;
    const valueKey = value != null ? value.toString() : undefined;
    const items = React.useMemo(() => {
        let iconMapping: Record<number, string> = {};
        let configError: string | undefined;
        if (configuration) {
            try {
                iconMapping = JSON.parse(configuration) as Record<number, string>;
            } catch {
                configError = `Invalid configuration: '${configuration}'`;
            }
        }

        return {
            error: configError,
            choices: options.map((item) => {
                return {
                    key: item.Value.toString(),
                    value: item.Value,
                    text: item.Label,
                    iconProps: { iconName: iconMapping[item.Value] },
                } as IChoiceGroupOption;
            }),
        };
    }, [options, configuration]);

    const onChangeChoiceGroup = React.useCallback(
        (ev?: unknown, option?: IChoiceGroupOption): void => {
            onChange(option ? (option.value as number) : undefined);
        },
        [onChange],
    );

    return (
        <>
            {items.error}
            <ChoiceGroup
                label={label}
                options={items.choices}
                selectedKey={valueKey}
                onChange={onChangeChoiceGroup}
            />
        </>
    );
});
ChoicesPickerComponent.displayName = 'ChoicesPickerComponent';

Notes

Le fichier a l’extension tsx, un fichier TypeScript qui prend en charge la syntaxe de style XML utilisée par React. Il est compilé en JavaScript standard par le processus de génération.

Remarques de conception ChoicesPickerComponent

Cette section inclut les commentaires sur la conception de ChoicesPickerComponent.

Il s’agit d’un composant fonctionnel

Il s’agit d’un composant fonctionnel React, mais il pourrait également s’agir d’un composant de classe. Ceci dépend de votre style de codage préféré. Les composants de classe et les composants fonctionnels peuvent aussi être mélangés dans le même projet. Les composants de fonction et de classe utilisent la syntaxe de style tsx utilisée par React. Informations complémentaires : Composants de fonction et de classe

Réduire la taille de bundle.js

Lors de l’importation des composants ChoiceGroup Fluent UI à l’aide d’importations basées sur le chemin, au lieu de :

import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react';

nous utilisons :

import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react/lib/ChoiceGroup';

De cette façon, la taille du regroupement est plus petite, pour des besoins en capacité moindre et de meilleures performances d’exécution.

Une autre possibilité consisterait à utiliser Tree Shaking.

Description des propriétés

Les propriétés d’entrée ont les attributs suivants qui sont fournis par index.ts dans la méthode updateView :

prop Description
label Utilisé pour étiqueter le composant. Il est lié à l’étiquette de champ de métadonnées fournie par le contexte parent, à l’aide du langage d’interface utilisateur sélectionné dans l’application pilotée par modèle.
value Lié à la propriété d’entrée définie dans le manifeste. Il peut être nul si l’enregistrement est nouveau ou si le champ n’est pas défini. TypeScript null est utilisé plutôt que undefined lors du transfert/retour des valeurs de propriété.
options Si un composant de code est lié à une colonne de choix dans une application pilotée par modèle, la propriété contient OptionMetadata qui décrit les choix disponibles. Vous le transmettez au composant afin qu’il puisse rendre chaque élément.
configuration Le composant a pour but d’afficher une icône pour chaque choix disponible. La configuration est fournie par le créateur d’applications lorsqu’il ajoute le composant de code à un formulaire. Cette propriété accepte une chaîne JSON qui mappe chaque valeur de choix numérique à un nom d’icône Fluent UI. Par exemple, {"0":"ContactInfo","1":"Send","2":"Phone"}
onChange Si l’utilisateur modifie la sélection des choix, le composant React déclenche l’événement onChange. Le composant de code appelle alors notifyOutputChanged pour que l’application pilotée par modèle mette à jour la colonne avec la nouvelle valeur.

Composant React contrôlé

Deux types de composants React sont disponibles :

Type Description
Non contrôlé Conservent leur état interne et utilisent les propriétés d’entrée uniquement comme valeurs par défaut.
Contrôlé Restituez la valeur transmise par les propriétés du composant. Si l’événement onChange ne met pas à jour les valeurs de propriété, l’utilisateur n’observe aucune modification dans l’interface utilisateur.

Le composant ChoicesPickerComponent est contrôlé, autrement dit, dès que l’application pilotée par modèle a mis à jour la valeur (après l’appel notifyOutputChanged), il appelle updateView avec la nouvelle valeur, qui est ensuite transmise aux propriétés du composant, ce qui provoque un nouveau rendu qui affiche la valeur mise à jour.

Affectation de déstructuration

L’affectation de la constante props : const { label, value, options, onChange, configuration } = props; utilise l’affectation déstructurante. De cette façon, vous extrayez les attributs nécessaires au rendu des propriétés, plutôt que de les préfixer avec props à chaque utilisation.

Utilisation des composants et des crochets React

Ce qui suit explique comment ChoicesPickerComponent.tsx utilise les composants et les crochets React :

Item Explication
React.memo Pour inclure dans un wrapper le composant fonctionnel afin qu′il ne soit pas rendu sauf si les propriétés d′entrée ont changé.
React.useMemo Garantir que le tableau d’éléments créé n’est muté que si les propriétés d’entrée options ou configuration ont changé. Il s’agit d’une bonne pratique en matière de composants fonctionnels qui réduit les rendus inutiles des composants enfants.
React.useCallback Créer une fermeture de rappel appelée si la valeur ChoiceGroup Fluent UI change. Ce hook React garantit que la fermeture de rappel n’est mutée que lorsque la propriété d’entrée onChange est changée. Il s’agit d’une meilleure pratique de performance identique à useMemo.

Comportement d’erreur pour la propriété d’entrée de configuration

Si l’analyse de la propriété d’entrée de configuration JSON échoue, l’erreur est rendue en utilisant items.error.

Mettre à jour index.ts pour rendre le composant ChoicesPicker

Vous devez mettre à jour le index.ts file généré pour rendre le ChoicesPickerComponent.

Lors de l’utilisation de React dans un composant de code, le rendu du composant racine est effectué dans la méthode updateView. Toutes les valeurs nécessaires au rendu du composant sont transmises au composant de manière à ce que, si elles sont modifiées, il est mis à jour.

Ajouter des instructions d’importation et initialiser les icônes

Avant d’ajouter ChoicesPickerComponent à index.ts, ajoutez ce qui suit en haut du fichier :

import { IInputs, IOutputs } from "./generated/ManifestTypes";

Notes

L′importation de initializeIcons est obligatoire car vous utilisez le jeu d′icônes Fluent UI. Vous devez appeler initializeIcons pour charger les icônes à l′intérieur du faisceau de test. Dans les applications pilotées par modèle, elles sont déjà initialisées.

Ajouter des attributs à la classe ChoicesPicker

Le composant de code conserve son état d′instance en utilisant des attributs. (Ceci est différent de l′état du composant React). Dans la classe index.ts ChoicesPicker, ajoutez les attributs suivants :

export class ChoicesPicker implements ComponentFramework.StandardControl<IInputs, IOutputs> {

La table suivante explique ces attributs :

Attribute Description
notifyOutputChanged Contient une référence à la méthode utilisée pour notifier à l’application pilotée par modèle qu’un utilisateur a modifié une valeur de choix et que le composant de code est prêt à la retransmettre au contexte parent.
rootContainer Élément DOM HTML créé pour contenir le composant de code dans l’application pilotée sur modèle.
selectedValue Contient l’état du choix sélectionné par l’utilisateur afin qu’il puisse être retourné dans la méthode getOutputs.
context Contexte Power Apps component framework utilisé pour lire les propriétés définies dans le manifeste et les autres propriétés d’exécution, et qui accède aux méthodes API telles que trackContainerResize.

Mettre à jour la méthode init

Pour définir ces attributs, mettez à jour la méthode init.

public init(
    context: ComponentFramework.Context<IInputs>, 
    notifyOutputChanged: () => void, 
    state: ComponentFramework.Dictionary, 
    container: HTMLDivElement): 
    void {
    // Add control initialization code
}

La méthode init est appelée lorsque le composant de code est initialisé sur un écran d’application.

Ajouter la méthode onChange

Si l’utilisateur modifie la valeur sélectionnée, vous devez appeler notifyOutputChanged à partir de l’événement onChange. Ajoutez une fonction :

onChange = (newValue: number | undefined): void => {
     this.selectedValue = newValue;
     this.notifyOutputChanged();
};

Mettre à jour la méthode getOutputs

public getOutputs(): IOutputs {
    return {};
}

Conseil

Si vous avez déjà écrit des scripts d′API client dans des applications pilotées par modèle, vous avec l′habitude d′utiliser le contexte de formulaire pour mettre à jour les valeurs d′attribut. Les composants de code ne doivent jamais accéder à ce contexte. À la place comptez sur notifyOutputChanged et sur getOutputs pour fournir une ou plusieurs valeurs modifiées. Il n′est pas nécessaire de renvoyer toutes les propriétés liées définies dans l′interface IOutput, uniquement celles qui ont changé de valeur.

Mettre à jour la méthode updateView

Maintenant, mettez à jour updateView pour rendre ChoicesPickerComponent :

public updateView(context: ComponentFramework.Context<IInputs>): void {
    // Add code to update control view
}

Notez que vous extrayez l′étiquette et les options de context.parameters.value et value.raw fournit le choix numérique sélectionné ou null si aucune valeur n′est sélectionnée.

Modifier la fonction destroy

Enfin, vous devez procéder à une réorganisation lorsque le composant de code est détruit :

public destroy(): void {
    // Add code to cleanup control if necessary
}

Plus d’informations : ReactDOM.unmountComponentAtNode

Commencer le faisceau de test

Assurez-vous que tous les fichiers sont enregistrés et, sur le terminal, utilisez :

npm start watch

Vous remarquez que le faisceau de test commence avec le sélecteur de choix affiché dans une nouvelle fenêtre de navigateur. Initialement, il affiche une erreur car la propriété de chaîne configuration a la valeur par défaut val. Définissez la configuration de sorte qu′elle mappe les choix par défaut du faisceau de test 0, 1 et 2 avec les icônes Fluent UI suivantes :

{"0":"ContactInfo","1":"Send","2":"Phone"}

Tester les choix du faisceau avec des icônes.

Si vous modifiez l′option sélectionnée, vous affichez la valeur dans le volet Entrées de données à droite. De plus, si vous modifiez la valeur, le composant affiche la valeur associée mise à jour.

Prise en charge de la sécurité en lecture seule et au niveau des colonnes

Lors de la création de composants field d’applications pilotées par modèle, les applications d’entreprise doivent respecter l’état de contrôle lorsqu’elles sont en lecture seule ou masquées en raison de la sécurité au niveau des colonnes. Si le composant de code n′affiche pas une interface utilisateur en lecture seule lorsque la colonne est en lecture seule, dans certains cas (par exemple, si un enregistrement est inactif), une colonne peut être mise à jour par l′utilisateur là où elle ne devrait pas être. Pour plus d’informations : Sécurité au niveau des colonnes pour contrôler l’accès.

Modifier la méthode updateView pour la sécurité en lecture seule et au niveau des colonnes

Dans index.ts, modifiez la méthode updateView pour ajouter le code suivant afin d’obtenir les indicateurs disabled et masked :

public updateView(context: ComponentFramework.Context<IInputs>): void {
    const { value, configuration } = context.parameters;
    if (value && value.attributes && configuration) {
        ReactDOM.render(
            React.createElement(ChoicesPickerComponent, {
                label: value.attributes.DisplayName,
                options: value.attributes.Options,
                configuration: configuration.raw,
                value: value.raw,
                onChange: this.onChange,
            }),
            this.rootContainer,
        );
    }
}

La valeur value.security est renseignée uniquement dans une application pilotée par modèle si la configuration de sécurité au niveau des colonnes est appliquée à la colonne liée.

Ces valeurs peuvent ensuite être transmises au composant React par ses propriétés.

Modifier ChoicesPickerComponent pour ajouter les propriétés désactivées et masquées

Dans ChoicesPickerComponent.tsx, vous pouvez accepter les propriétés disabled et masked en les ajoutant à l’interface ChoicesPickerComponentProps :

export interface ChoicesPickerComponentProps {
    label: string;
    value: number | null;
    options: ComponentFramework.PropertyHelper.OptionMetadata[];
    configuration: string | null;
    onChange: (newValue: number | undefined) => void;
}

Modifier les propriétés ChoicesPickerComponent

Ajoutez les nouveaux attributs aux propriétés.

export const ChoicesPickerComponent = React.memo((props: ChoicesPickerComponentProps) => {
    const { label, value, options, configuration, onChange } = props;

Modifier le nœud de retour ChoicesPickerComponent

Dans ChoicesPickerComponent, lors du renvoi des nœuds React, utilisez ces nouvelles propriétés d’entrée pour vérifier que le sélecteur est désactivé ou masqué

return (
    <>
        {items.error}
        <ChoiceGroup
            label={label}
            options={items.choices}
            selectedKey={valueKey}
            onChange={onChangeChoiceGroup}
        />
    </>
);

Notes

Vous ne devriez voir aucune différence dans le faisceau de test, car il ne peut pas simuler les champs en lecture seule ou la sécurité au niveau des colonnes. Vous devrez tester cela après avoir déployé le contrôle dans une application pilotée par modèle.

Rendre le composant de code réactif

Les composants de code peuvent être affichés sur le web, des tablettes et des applications mobiles. Il est important de prendre en compte l′espace disponible. Affichez le composant de choix sous la forme d’une liste déroulante si la largeur disponible est limitée.

Importer le composant Dropdown et les icônes

Dans ChoicesPickerComponent.tsx, le composant rend la petite version avec le composant Fluent UI Dropdown, afin de l’ajouter aux importations :

import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react/lib/ChoiceGroup';
import * as React from 'react';

Ajouter une propriété formFactor

Commencez par mettre à jour le composant de code pour qu′il s′affiche différemment en fonction d′une nouvelle propriété formFactor. Ajoutez l’attribut suivant à l’interface ChoicesPickerComponentProps :

export interface ChoicesPickerComponentProps {
  label: string;
  value: number | null;
  options: ComponentFramework.PropertyHelper.OptionMetadata[];
  configuration: string | null;
  onChange: (newValue: number | undefined) => void;
  disabled: boolean;
  masked: boolean;
}

Ajouter formFactor aux propriétés ChoicesPickerComponent

Ajoutez formFactor aux propriétés.

export const ChoicesPickerComponent = React.memo((props: ChoicesPickerComponentProps) => {
    const { label, value, options, configuration, onChange, disabled, masked  } = props;

Ajouter des méthodes et modifier pour prendre en charge le composant déroulant

Le composant déroulant a besoin de différentes méthodes d’affichage.

  1. Au-dessus de ChoicesPickerComponent, ajoutez ce qui suit :

    const iconStyles = { marginRight: '8px' };
    
    const onRenderOption = (option?: IDropdownOption): JSX.Element => {
       if (option) {
           return (
             <div>
                 {option.data && option.data.icon && (
                   <Icon
                       style={iconStyles}
                       iconName={option.data.icon}
                       aria-hidden="true"
                       title={option.data.icon} />
                 )}
                 <span>{option.text}</span>
             </div>
           );
       }
       return <></>;
    };
    
    const onRenderTitle = (options?: IDropdownOption[]): JSX.Element => {
       if (options) {
           return onRenderOption(options[0]);
       }
       return <></>;
    };
    

    Ces méthodes sont utilisées par Dropdown pour afficher l’icône correcte en regard de la valeur déroulante.

  2. Ajoutez une nouvelle méthode onChangeDropDown.

    Nous avons également besoin d’une méthode onChange pour Dropdown qui soit identique au gestionnaire d’événements ChoiceGroup. Au-dessous de l’élément onChangeChoiceGroup existant, ajoutez la nouvelle version Dropdown :

    const onChangeDropDown = React.useCallback(
           (ev: unknown, option?: IDropdownOption): void => {
               onChange(option ? (option.data.value as number) : undefined);
           },
           [onChange],
       );
    

Modifier la sortie affichée

Apportez les modifications suivantes à la nouvelle propriété formFactor.

return (
  <>
      {items.error}
      {masked && '****'}

      {!items.error && !masked && (
        <ChoiceGroup
            label={label}
            options={items.choices}
            selectedKey={valueKey}
            disabled={disabled}
            onChange={onChangeChoiceGroup}
        />
      )}
  </>
);

Notez que vous sortez le composant ChoiceGroup lorsque formFactor est grand et utilisez Dropdown lorsqu′il est petit.

Retourner DropdownOptions

Enfin, dans ChoicesPickerComponent.tsx, nous devons mapper les métadonnées des options légèrement différemment sur celles utilisées par ChoicesGroup. Ainsi, dans le bloc de retour items sous les choices existants : options.map, ajoutez ce qui suit :

return {
    error: configError,
    choices: options.map((item) => {
      return {
          key: item.Value.toString(),
          value: item.Value,
          text: item.Label,
          iconProps: { iconName: iconMapping[item.Value] },
      } as IChoiceGroupOption;
    }),
};

Modifier index.ts

Maintenant que le composant de choix s’affiche différemment en fonction de la propriété formFactor, vous devez transmettre la valeur correcte de l’appel de rendu dans index.ts.

Ajouter SmallFormFactorMaxWidth et FormFactors enum

Ajoutez ce qui suit au-dessus de la classe export class ChoicesPicker dans index.ts.

const SmallFormFactorMaxWidth = 350;

const enum FormFactors {
  Unknown = 0,
  Desktop = 1,
  Tablet = 2,
  Phone = 3,
}

SmallFormFactorMaxWidth est la largeur lorsque le composant commence à s’affiche en utilisant Dropdown plutôt que le composant ChoiceGroup. FormFactors enum est utilisé pour plus de commodité lors de l’appel de context.client.getFormFactor.

Ajouter du code pour détecter formFactor

Ajoutez ce qui suit aux propriétés React.createElement sous les propriétés existantes :

React.createElement(ChoicesPickerComponent, {
    label: value.attributes.DisplayName,
    options: value.attributes.Options,
    configuration: configuration.raw,
    value: value.raw,
    onChange: this.onChange,
    disabled: disabled,
    masked: masked,
}),

Demander des mises à jour pour le redimensionnement

Étant donné que vous utilisez context.mode.allocatedWidth, vous devez indiquer à l′application pilotée par modèle que vous souhaitez recevoir les mises à jour (via un appel à updateView) si la largeur disponible change. Pour cela, dans la méthode init, ajoutez un appel à context.mode.trackContainerResize :

public init(
    context: ComponentFramework.Context<IInputs>, 
    notifyOutputChanged: () => void, 
    state: ComponentFramework.Dictionary, 
    container: HTMLDivElement): 
    void {
      this.notifyOutputChanged = notifyOutputChanged;
      this.rootContainer = container;
      this.context = context;
}

Essayer dans le faisceau de test

Enregistrez maintenant toutes les modifications pour qu′elles apparaissent automatiquement dans la fenêtre de navigateur du faisceau de test (car npm start watch continue de s′exécuter). Vous pouvez maintenant modifier la valeur Largeur du conteneur de composants entre 349 et 350, et constater que le comportement du rendu change. Vous pouvez également permuter Facteur de forme entre Web et Téléphone, et observer le même comportement.

trackContainerResize.

Localisation

Pour prendre en charge plusieurs langues, le composant de code peut contenir un fichier de ressources qui fournit les traductions des chaînes de conception et d’exécution.

  1. Ajoutez un nouveau fichier à l’emplacement ChoicesPicker\strings\ChoicesPicker.1033.resx. Pour ajouter des étiquettes pour un autre paramètre régional, modifiez 1033 (en-us) et choisissez le paramètre régional de votre choix.

  2. À l’aide de l’éditeur de ressources de Visual Studio Code, saisissez ce qui suit :

    Nom  active
    ChoicesPicker_Name Sélecteur de choix (piloté par modèle)
    ChoicesPicker_Desc Affiche les choix sous forme de sélecteur avec des icônes
    Value_Name active
    Value_Desc Le champ Choix à associer au contrôle
    Configuration_Name Icône Configuration du mappage
    Configuration_Desc Configuration qui mappe la valeur de choix à une icône d’interface utilisateur fluide. Par exemple, {"1":"ContactInfo","2":"Envoyer"}

    Sinon, définissez le contenu du fichier .resx avec le XML suivant :

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
        <xsd:element name="root" msdata:IsDataSet="true">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <xsd:element name="metadata">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0"/>
                  </xsd:sequence>
                  <xsd:attribute name="name" use="required" type="xsd:string"/>
                  <xsd:attribute name="type" type="xsd:string"/>
                  <xsd:attribute name="mimetype" type="xsd:string"/>
                  <xsd:attribute ref="xml:space"/>
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="assembly">
                <xsd:complexType>
                  <xsd:attribute name="alias" type="xsd:string"/>
                  <xsd:attribute name="name" type="xsd:string"/>
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="data">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
                    <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2"/>
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1"/>
                  <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3"/>
                  <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4"/>
                  <xsd:attribute ref="xml:space"/>
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="resheader">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1"/>
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required"/>
                </xsd:complexType>
              </xsd:element>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:schema>
      <resheader name="resmimetype">
        <value>text/microsoft-resx</value>
      </resheader>
      <resheader name="version">
        <value>2.0</value>
      </resheader>
      <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <resheader name="writer">
        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <data name="ChoicesPicker_Name" xml:space="preserve">
        <value>Choices Picker (Model Driven)</value>
        <comment/>
      </data>
      <data name="ChoicesPicker_Desc" xml:space="preserve">
        <value>Shows choices as a picker with icons</value>
        <comment/>
      </data>
      <data name="Value_Name" xml:space="preserve">
        <value>Value</value>
        <comment/>
      </data>
      <data name="Value_Desc" xml:space="preserve">
        <value>The choices field to bind the control to</value>
        <comment/>
      </data>
      <data name="Configuration_Name" xml:space="preserve">
        <value>Icon Mapping Configuration</value>
        <comment/>
      </data>
      <data name="Configuration_Desc" xml:space="preserve">
        <value>Configuration that maps the choice value to a fluent ui icon. E.g. {"1":"ContactInfo","2":"Send"}</value>
        <comment/>
      </data>
    </root>
    

    Conseil

    Il n′est pas conseillé de modifier les fichiers resx directement. Au lieu de cela, utilisez soit l′éditeur de ressources de Visual Studio Code, soit une extension pour Visual Studio Code.

Mettre à jour le manifeste pour les chaînes de ressources

Maintenant que vous avez les chaînes de ressources, vous pouvez les référencer en mettant à jour ControlManifest.Input.xml comme suit :

<?xml version="1.0" encoding="utf-8" ?>
<manifest>
  <control namespace="SampleNamespace"
    constructor="ChoicesPicker"
    version="0.0.1"
    display-name-key="ChoicesPicker"
    description-key="ChoicesPicker description"
    control-type="standard">
    <external-service-usage enabled="false">
    </external-service-usage>
    <property name="value"
      display-name-key="Value"
      description-key="Value of the Choices Control"
      of-type="OptionSet"
      usage="bound"
      required="true"/>
    <property name="configuration"
      display-name-key="Icon Mapping"
      description-key="Configuration that maps the choice value to a fluent ui icon."
      of-type="Multiple"
      usage="input"
      required="true"/>
    <resources>
      <code path="index.ts"
        order="1"/>
    </resources>
  </control>
</manifest>

Vous remarquez que :

  1. Les valeurs display-name-key et description-key pointent maintenant vers la clé correspondante dans le fichier resx.
  2. L′élément resources contient une entrée supplémentaire indiquant que le composant de code doit charger les ressources à partir du fichier référencé.

Si vous avez besoin de chaînes supplémentaires au niveau du composant, vous pouvez les ajouter dans resx, puis charger les chaînes au moment de l’exécution en utilisant getString. Pour d’informations : Implémentation du composant d’API de localisation.

Notes

L’une des limitations du faisceau de test est qu’il ne charge pas les fichiers de ressources, vous devez donc déployer le composant sur Microsoft Dataverse pour le tester complètement.

Déploiement et configuration dans une application pilotée sur modèle

Après avoir testé les fonctionnalités de base avec le faisceau de test, vous devez déployer le composant sur Microsoft Dataverse afin que le composant de code soit testé de bout en bout dans une application pilotée par modèle.

  1. Dans l′environnement Dataverse, vérifiez qu′un éditeur est créé avec un préfixe samples :

    Ajouter un nouvel éditeur.

    Il peut aussi s’agir de votre éditeur, à condition que vous mettiez à jour le paramètre de préfixe de l’éditeur dans l’appel de pac pcf push ci-dessous. Plus d’informations : Créer un éditeur de solutions.

  2. Une fois l′éditeur enregistré, vous êtes prêt à autoriser la CLI Microsoft Power Platform sur votre environnement pour pousser le composant de code compilé. Sur la ligne de commande, entrez :

    pac auth create --url https://myorg.crm.dynamics.com
    

    Remplacez myorg.crm.dynamics.com par l’URL de votre environnement Dataverse. Connectez-vous avec les privilèges de l’administrateur système lorsque vous y êtes invité. Les privilèges fournis par ces rôles sont nécessaires pour déployer des composants de code sur Dataverse.

  3. Pour déployer votre composant de code, utilisez :

    pac pcf push --publisher-prefix samples
    

    Notes

    Si vous recevez l′erreurMissing required tool: MSBuild.exe/dotnet.exe, ajoutez MSBuild.exe/dotnet.exe dans la variable d′environnement Path ou utilisez Developer Command Prompt for Visual Studio Code. Vous devez installer soit Visual Studio 2019 pour Windows et Mac, soit Build Tools pour Visual Studio 2019. Assurez-vous de sélectionner la charge de travail .NET build tools comme décrit dans les conditions préalables.

  4. Une fois terminé, ce processus crée une solution temporaire nommée PowerAppTools_samples dans votre environnement. Le composant de code ChoicesPicker est ajouté à cette solution. Vous pourrez déplacer le composant de code dans votre solution ultérieurement si nécessaire. Plus d’informations : Gestion du cycle de vie des applications de composants de code (ALM).

    Solution temporaire PowerAppsTools_samples.

  5. Ajoutez ensuite le composant de code au formulaire Contacts en accédant à Formulaire principal dans Éditeur classique, sélectionnez Méthode de communication préférée > Modifier les propriétés > Onglet Contrôles > Ajouter un contrôle > Sélectionner le sélecteur de choix > Ajouter.

    Notes

    À l’avenir, l’éditeur classique ne sera plus nécessaire pour configurer les composants de code sur les formulaires des applications pilotées par modèle.

  6. Définissez les propriétés suivantes sur le composant :

    • Définissez le sélecteur de choix par défaut pour le web, le téléphone et la tablette.

    • Entrez la chaîne suivante pour Configuration du mappage des icônes en sélectionnant l’icône d’édition et en sélectionnant Associer à une valeur statique.

      {
          "1":"ContactInfo",
          "2":"Send", 
          "3":"Phone",
          "4":"Fax",
          "5":"DeliveryTruck"
      }
      

      Il s’agit des icônes Fluent UI qui seront utilisées pour chaque valeur de choix.

      Propriétés de contrôle.

    • Sélectionnez l’onglet Affichage et décochez la case Afficher l’étiquette sur le formulaire car vous allez afficher l’étiquette au-dessus du sélecteur de choix.

  7. Enregistrez et publiez le formulaire.

  8. Ouvrez un enregistrement de contact dans l’application pilotée par modèle avec le bon formulaire sélectionné. Vous affichez maintenant le composant de code ChoicesPicker à la place du contrôle déroulant standard. (Il est possible que vous deviez recharger la page pour que le composant apparaisse).

    Notes

    Vous constatez que l’alignement du texte est légèrement différent dans le faisceau de test par rapport aux applications pilotées par modèle. Cette différence est liée au fait que le faisceau de test utilise des règles CSS différentes de celles des applications pilotées sur modèle. Pour cette raison, il est conseillé de toujours tester le composant de code de bout en bout après le déploiement.

Débogage après le déploiement sur Dataverse

Si vous devez apporter d′autres modifications au composant, vous n′avez pas besoin de le déployer à chaque fois. Utilisez plutôt la technique décrite dans Déboguer les composants de code pour créer une règle AutoResponder Fiddler pour charger le fichier à partir du système de fichiers local pendant l′exécution de npm start watch.

Notes

Il est possible que vous n′ayez pas besoin de déboguer après le déploiement dans Dataverse si le faisceau de test parvient à tester toutes les fonctionnalités. Il est toutefois conseillé de toujours déployer et tester dans Dataverse avant de distribuer le composant de code.

La règle AutoResponder ressemblerait à ce qui suit :

REGEX:(.*?)((?'folder'css|html)(%252f|\/))?SampleNamespace\.ChoicesPicker[\.\/](?'fname'[^?]*\.*)(.*?)$
C:\repos\ChoicesPicker\out\controls\ChoicesPicker\${folder}\${fname}

Règle AutoResponder.

Vous devez utiliser l’option Vider le cache et actualiser sur votre session de navigateur pour le fichier AutoResponder à récupérer. Une fois chargé, actualisez le navigateur car Fiddler ajoute un en-tête de contrôle du cache au fichier pour éviter qu’il ne soit mis en cache.

Une fois vos modifications terminées, incrémentez la version du correctif dans le manifeste, puis procédez au déploiement en utilisant pac pcf push.

À ce stade, vous avez déployé une version de développement, qui n′est pas optimisée et qui s′exécute plus lentement au moment de l′exécution. Vous pouvez choisir de déployer une version optimisée en utilisant pac pcf push en éditant ChoicesPicker.pcfproj. Sous OutputPath, ajoutez ce qui suit :

<PcfBuildMode>production</PcfBuildMode>

Gestion du cycle de vie des applications (ALM) avec Microsoft Power Platform
Référence d’API Power Apps component framework
Création de votre premier composant
Déboguer des composants de code

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).