Partager via


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

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

En plus de cela, vous allez également vous assurer que le composant de code suit les conseils de bonnes pratiques :

  1. Utilisation de l’interface utilisateur Microsoft Fluent pour la cohérence et l’accessibilité
  2. Localisation des étiquettes des composants de code au moment de la conception et de l’exécution
  3. Assurance que le composant de code est piloté par les métadonnées pour une meilleure réutilisation
  4. Assurer que l'élément de code s'affiche en fonction du format et de la largeur disponible, tout en affichant une liste déroulante compacte avec des icônes lorsque l'espace est limité.

Composant ChoicesPicker.

Code

Vous pouvez télécharger l’exemple complet à partir de PowerApps-Samples/component-framework/ChoicesPickerControl/.

Créer un pcfproj projet

Note

Avant de commencer, vérifiez que vous avez installé tous les composants requis.

Pour créer un nouveau pcfproj:

  1. Créez un dossier pour contenir votre composant de code. Par exemple : C:\repos\ChoicesPicker.

  2. Ouvrez Visual Studio Code et accédez à Fichier>Ouvrir le dossier, puis sélectionnez le ChoicesPicker dossier créé à l’étape précédente. Si vous avez ajouté les extensions de l’Explorateur Windows pendant l’installation de Visual Studio Code, vous pouvez également utiliser l’option Ouvrir avec Code dans le dossier. Vous pouvez également ajouter n’importe quel dossier dans Visual Studio Code à l’aide code . de l’invite de commandes lorsque le répertoire actif est défini sur cet emplacement.

  3. Dans le nouveau terminal PowerShell Visual Studio Code (Terminal>New 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 le formulaire court :

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

Cela ajoute un nouveau ChoicesPicker.pcfproj et des fichiers associés au dossier actif, y compris un package.json qui définit les modules requis. La commande ci-dessus exécutera également pour vous la commande npm install afin d'installer les modules nécessaires.

Running 'npm install' for you...

Note

Si vous recevez l’erreur The term 'npm' is not recognized as the name of a cmdlet, function, script file, or operable program., vérifiez que vous avez installé node.js (version LTS est recommandée) et tous les autres prérequis.

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

Vous pouvez voir que le modèle inclut un index.ts fichier ainsi que différents fichiers de configuration. Il s’agit du point de départ de votre composant de code et contient les méthodes de cycle de vie décrites dans l’implémentation du composant.

Installer l’interface utilisateur Microsoft Fluent

Vous utiliserez l’interface utilisateur Microsoft Fluent 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 packages.json dossier et les installe dans le node_modules dossier. 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 l’interface utilisateur Microsoft Fluent est qu’elle offre 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 ChoicesPicker\ControlManifest.Input.xml fichier définit les métadonnées qui décrivent le comportement du composant de code. Les attributs de contrôle contiennent déjà l’espace de noms et le nom de votre composant.

Vous devez définir les propriétés liées et d’entrée suivantes :

Nom Usage Type Descriptif
Valeur bound OptionSet Cette propriété sera liée à la colonne de choix. Le composant de code reçoit la valeur actuelle, puis avertit le contexte parent lorsque la valeur a changé.
Mappage d’icônes input Plusieurs lignes de texte Cette propriété aura sa valeur définie lorsque le créateur d’application ajoute le composant de code au formulaire. Il contient une chaîne JSON pour configurer les icônes qui peuvent être utilisées pour chaque valeur de choix.

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

Conseil / Astuce

Vous pouvez trouver le code XML plus facile à lire en le mettant en forme afin que les attributs apparaissent sur des lignes distinctes. Recherchez et installez un outil de mise en forme XML de votre choix dans Visual Studio Code Marketplace : recherchez des extensions de mise en forme xml.

Les exemples ci-dessous ont été mis en forme avec des attributs sur des lignes distinctes pour faciliter leur lecture.

Remplacer l’exempleProperty existant par de nouvelles propriétés

Ouvrez le ChoicesPicker\ControlManifest.Input.xml et collez les définitions de propriétés suivantes à l’intérieur de l’élément de contrôle, en remplaçant le contenu existant de sampleProperty.

<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 verrez que :

  • Un fichier ChoicesPicker\generated\ManifestTypes.d.ts généré automatiquement est ajouté à votre projet. Cela est généré dans le cadre du processus de génération à partir du ControlManifest.Input.xml et fournit les types nécessaires pour interagir avec les propriétés d'entrée/sortie.

  • La sortie de build est ajoutée au out répertoire. Le bundle.js est le JavaScript transpilé qui s’exécute à l’intérieur du navigateur. Le ControlManifest.xml est une version reformatée du fichier ControlManifest.Input.xml qui est utilisée pendant le déploiement.

    Note

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

Implémenter le composant ChoicesPicker Fluent UI React

Lorsque le composant de code utilise React, il doit y avoir un composant racine unique rendu dans la updateView méthode. Dans le ChoicesPicker dossier, ajoutez un nouveau fichier TypeScript nommé ChoicesPickerComponent.tsxet 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';

Note

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

Les notes de conception de "ChoicesPickerComponent"

Cette section inclut des commentaires sur la conception du ChoicesPickerComponent.

Il s’agit d’un composant fonctionnel

Il s’agit d’un composant fonctionnel React, mais également, il peut s’agir d’un composant de classe. Cela est basé sur votre style de codage préféré. Les composants de classe et les composants fonctionnels peuvent également être mélangés dans le même projet. Les composants de fonction et de classe utilisent la syntaxe de tsx style XML utilisée par React. Plus d’informations : Composants de fonction et de classe

Réduire la taille de bundle.js

Lors de l'importation des composants Fluent UI à l'aide d'importations basées sur le chemin ChoiceGroup, 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 de votre offre groupée sera plus petite, ce qui entraînera des exigences de capacité inférieures 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 seront fournis par index.ts dans la méthode updateView.

prop Descriptif
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. Cela peut être null lorsque l’enregistrement est nouveau ou que le champ n’est pas défini. TypeScript null est utilisé plutôt que undefined lors de la transmission/retour de valeurs de propriété.
options Lorsqu’un composant de code est lié à une colonne de choix dans une application basée sur un modèle, la propriété contient les OptionMetadata choix disponibles. Vous transmettez ce paramètre au composant pour qu’il puisse afficher chaque élément.
configuration L’objectif du composant est 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 Lorsque l’utilisateur modifie la sélection des choix, le composant React déclenche l’événement onChange . Le composant de code appelle ensuite l’application notifyOutputChanged pilotée par le modèle pour mettre à jour la colonne avec la nouvelle valeur.

Composant React contrôlé

Il existe deux types de composants React :

Type Descriptif
Incontrôlé Conservez leur état interne et utilisez uniquement les propriétés d’entrée 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 d’prop, l’utilisateur ne voit pas de modification dans l’interface utilisateur.

ChoicesPickerComponent est un composant contrôlé, donc une fois que l'application pilotée par modèle a mis à jour la valeur (après l'appel notifyOutputChanged), elle appelle updateView avec la nouvelle valeur, qui est ensuite transmise aux propriétés du composant, provoquant un nouveau rendu qui affiche la valeur actualisée.

Déstructuration de l’affectation

Affectation de la props constante : const { label, value, options, onChange, configuration } = props; utilise l’affectation par décomposition. De cette façon, vous extrayez les attributs requis pour rendre à partir des props, plutôt que de les préfixer avec props chaque fois qu’ils sont utilisés.

Utilisation des composants React et des hooks

Les éléments suivants expliquent comment ChoicesPickerComponent.tsx utiliser les composants et les hooks React :

Élément Explanation
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 Pour vous assurer que le tableau d’éléments créé n’est muté que lorsque les propriétés options d’entrée 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 bonne pratique de performances similaire à 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 affichée à l’aide de items.error.

Mettre à jour index.ts pour afficher le composant ChoicesPicker

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

Lorsque vous utilisez React à l’intérieur d’un composant de code, le rendu du composant racine est effectué à l’intérieur de la updateView méthode. 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 des icônes

Avant de pouvoir utiliser le ChoicesPickerComponent dans le index.ts, vous devez ajouter les éléments suivants en haut du fichier :

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

Note

L'importation de initializeIcons est requise, car vous utilisez l'ensemble d'icônes Fluent UI. Vous devez appeler initializeIcons pour charger les icônes à l’intérieur du harnais de test. Dans les applications basées sur des modèles, elles sont déjà initialisées.

Ajouter des attributs à la classe ChoicesPicker

Le composant de code conserve son état d’instance à l’aide d’attributs. (Ceci est différent de l’état du composant React). À l’intérieur de la index.tsChoicesPicker classe, ajoutez les attributs suivants :

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

Le tableau suivant décrit ces attributs :

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

Mettre à jour la init méthode

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

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

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

Ajouter la onChange méthode

Lorsque l’utilisateur modifie la valeur sélectionnée, vous devez appeler notifyOutputChanged depuis l’événement onChange. Ajouter une fonction :

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

Mettre à jour la getOutputs méthode

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

Conseil / Astuce

Si vous avez déjà écrit des scripts d’API client dans des applications basées sur des modèles, vous pouvez avoir 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. Au lieu de cela, fiez-vous à notifyOutputChanged et getOutputs pour fournir une ou plusieurs valeurs modifiées. Vous n’avez pas besoin de retourner toutes les propriétés liées définies dans l’interface IOutput , seules celles qui ont changé leur valeur.

Mettre à jour la updateView méthode

À présent, 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 depuis context.parameters.value, et que value.raw indique le choix numérique sélectionné, ou null si aucune valeur n'est choisie.

Modifier la fonction de destruction

Enfin, vous devez faire le ménage quand le composant du code est détruit.

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

Plus d’informations : ReactDOM.unmountComponentAtNode

Démarrer le harnais de test

Vérifiez que tous les fichiers sont enregistrés et utilisez le terminal pour :

npm start watch

Vous verrez que le harnais de test commence par le sélecteur de choix affiché à l’intérieur d’une nouvelle fenêtre de navigateur. Initialement, il affiche une erreur, car la propriété configuration de chaîne a la valeur valpar défaut. Définissez la configuration afin qu’elle mappe les choix par défaut du harnais de test 0, 1 et 2 avec les icônes d’interface utilisateur Fluent suivantes :

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

Testez les choix d’harnais avec les icônes.

Lorsque vous modifiez l’option sélectionnée, vous verrez la valeur dans le panneau Entrées de données à droite. En outre, 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 d’applications field basées sur des modèles, les applications doivent respecter l’état du contrôle en lecture seule ou masquée en raison de la sécurité au niveau des colonnes. Si le composant de code n’affiche pas d’interface utilisateur en lecture seule lorsque la colonne est en lecture seule, dans certaines circonstances (par exemple, lorsqu’un enregistrement est inactif), une colonne peut être mise à jour par l’utilisateur où elle ne doit pas être. Plus d’informations : Sécurité au niveau des colonnes pour contrôler l’accès.

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

Dans index.ts, modifiez la méthode updateView pour ajouter le code suivant permettant 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 passées dans le composant React via 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 du composant ChoicesPickerComponent

Ajoutez les nouveaux attributs aux props.

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

Modifier le nœud de retour du composant ChoicesPicker

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}
        />
    </>
);

Note

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 devez le tester après le déploiement du contrôle au sein d’une application pilotée par modèle.

Rendre le composant de code réactif

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

Importer le composant déroulant et les icônes

Dans ChoicesPickerComponent.tsx, le composant affiche la petite version à l’aide du composant Fluent UI Dropdown . Vous l’ajoutez donc aux importations :

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

Ajouter une propriété formFactor

Mettez à 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 de 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 les modifier pour la prise en charge du composant déroulant

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

  1. Au-dessus du ChoicesPickerComponent, ajoutez les éléments suivants :

    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 seront utilisées par Dropdown pour afficher l'icône correcte à côté de la valeur déroulante.

  2. Ajoutez une nouvelle onChangeDropDown méthode.

    Nous avons besoin d'une méthode onChange pour le Dropdown, similaire au gestionnaire d'événements ChoiceGroup. Juste en dessous de l’existant onChangeChoiceGroup, ajoutez la nouvelle Dropdown version :

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

Modifier la sortie rendue

Apportez les modifications suivantes pour utiliser la nouvelle formFactor propriété.

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

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

Vous pouvez voir que le composant ChoiceGroup s'affiche quand formFactor est volumineux et que vous utilisez Dropdown quand il est petit.

Retourner des options du menu déroulant

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 l’énumération SmallFormFactorMaxWidth et FormFactors

Ajoutez les éléments suivants juste au-dessus de la classe export class ChoicesPicker à l'intérieur de 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. The FormFactorsenum 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 des mises à jour (via un appel à updateView) lorsque la largeur disponible change. Vous faites cela dans la méthode init en ajoutant 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 harnais de test

Enregistrez maintenant toutes les modifications afin qu’elles soient automatiquement reflétées dans la fenêtre du navigateur du harness de test (car vous avez npm start watch toujours en cours d'exécution depuis plus tôt). Vous pouvez maintenant basculer la valeur de la largeur du conteneur de composants entre 349 et 350 et voir le rendu se comporter différemment. Vous pouvez également permuter le facteur de forme entre le web et le téléphone et voir le même comportement.

trackContainerResize.

Localisation

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

  1. Ajoutez un nouveau fichier à l’emplacement ChoicesPicker\strings\ChoicesPicker.1033.resx. Si vous souhaitez ajouter des étiquettes pour un autre paramètre régional, remplacez le 1033 (en-us) par celui de votre choix.

  2. À l’aide de l’éditeur de ressources Visual Studio Code, entrez les éléments suivants :

    Nom Valeur
    ChoicesPicker_Name Sélecteur de choix (piloté par le modèle)
    ChoicesPicker_Desc Affiche les choix en tant que sélecteur avec des icônes
    Value_Name Valeur
    Value_Desc Champ des choix pour lier le contrôle à
    Configuration_Name Configuration du mappage d’icônes
    Configuration_Desc Configuration qui associe la valeur de choix à une icône Fluent UI. Par exemple {"1 » :"ContactInfo »,"2 » :"Send"}

    Sinon, définissez le contenu du fichier .resx avec le code 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 / Astuce

    Il n’est pas recommandé de modifier resx les fichiers directement. L’éditeur de ressources Visual Studio Code ou une extension pour Visual Studio Code facilite cette opération.

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

Maintenant que vous disposez des chaînes de ressources, vous pouvez les référencer en les 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 pouvez voir que :

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

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

Note

L’une des limitations du harnais de test est qu’elle ne charge pas les fichiers de ressources. Vous devez donc déployer le composant sur Microsoft Dataverse pour tester entièrement votre composant.

Déploiement et configuration dans une application basée sur des modèles

Une fois que vous avez testé les fonctionnalités de base avec le harnais de test, vous devez déployer le composant sur Microsoft Dataverse afin que le composant de code puisse être entièrement testé de bout en bout à l’intérieur d’une application pilotée par modèle.

  1. Dans votre environnement Dataverse, vérifiez qu’il existe un éditeur créé avec un préfixe de samples:

    Ajoutez un nouvel éditeur.

    De même, il peut s’agir de votre éditeur, à condition que vous mettez à jour le paramètre de préfixe de l’éditeur dans l’appel à pac pcf push ci-dessous. Pour plus d’informations, créez un éditeur de solution.

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

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

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

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

    pac pcf push --publisher-prefix samples
    

    Note

    Si vous recevez l’erreur Missing required tool: MSBuild.exe/dotnet.exe, ajoutez MSBuild.exe/dotnet.exe la variable d’environnement Path ou utilisez Developer Command Prompt for Visual Studio Code. Vous devez installer Visual Studio 2019 pour Windows &Mac ou Build Tools pour Visual Studio 2019. Veillez à sélectionner la .NET build tools charge de travail comme indiqué dans les prérequis.

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

    Solution temporaire PowerAppsTools_sample.

  5. Ensuite, ajoutez le composant de code au formulaire Contacts par la navigation dans le formulaire principal de l’éditeur classique, sélectionnez 'Méthode de contact préférée', allez à l'onglet Modifier les propriétés, puis Contrôles, Ajoutez un contrôle, et enfin sélectionnez Choix du sélecteur, puis Ajoutez.

    Note

    À l’avenir, l’éditeur classique n’est pas nécessaire pour configurer des composants de code sur des formulaires d’applications basées sur des modèles.

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

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

    • Entrez la chaîne suivante pour la configuration du mappage d’icônes en sélectionnant l’icône de modification et en sélectionnant Lier à une valeur statique.

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

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

      Propriétés du contrôle.

    • Sélectionnez l’onglet Affichage et décochez l’étiquette Afficher dans le formulaire , car vous afficherez l’étiquette au-dessus du sélecteur de choix.

  7. Enregistrez et publiez le formulaire.

  8. Ouvrez un enregistrement de contact à l’intérieur de l’application pilotée par modèle en sélectionnant le formulaire approprié. Vous affichez maintenant le composant de code ChoicesPicker à la place du contrôle déroulant standard. (Vous devrez peut-être effectuer un rechargement dur de la page pour que le composant s’affiche).

    Note

    Vous pouvez voir que l’alignement du texte est légèrement différent dans le harnais de test par rapport aux applications basées sur des modèles. Cela est dû au fait que le harnais de test a des règles CSS différentes à celles des applications basées sur des modèles. Pour cette raison, il est recommandé de toujours tester entièrement votre composant de code après le déploiement.

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

Si vous devez apporter d’autres modifications à votre composant, vous n’avez pas besoin de 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.

Note

Vous n’avez peut-être pas besoin de déboguer après le déploiement vers Dataverse si toutes les fonctionnalités peuvent être testées à l’aide du harnais de test. Toutefois, il est recommandé de toujours déployer et de tester à l’intérieur de Dataverse avant de distribuer votre composant de code.

L’AutoResponder ressemble à ce qui suit :

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

Règle AutoResponder.

Vous devez vider le cache et actualiser en dur sur votre session de navigateur pour que le fichier AutoResponder soit récupéré. Une fois chargé, vous pouvez actualiser le navigateur, car Fiddler ajoute un en-tête de contrôle de cache au fichier pour l’empêcher d’être mis en cache.

Une fois vos modifications terminées, vous pouvez incrémenter la version du correctif dans le manifeste, puis redéployer à l’aide de pac pcf push.

Jusqu’à présent, vous avez déployé une build de développement qui n’est pas optimisée et s’exécute plus lentement au moment de l’exécution. Vous pouvez choisir de déployer une build optimisée à l’aide de pac pcf push en modifiant le ChoicesPicker.pcfproj. Sous le OutputPath, ajoutez les éléments suivants :

<PcfBuildMode>production</PcfBuildMode>

Application Lifecycle Management (ALM) avec Microsoft Power Platform
Référence d'API d'infrastructure Power Apps component framework
Création de votre premier composant
Déboguer des composants de code