Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial, creará un componente de aplicación field controlado por modelos e implementará, configurará y probará el componente en un formulario mediante Visual Studio Code. Este componente de código muestra un conjunto de opciones en el formulario con un icono junto a cada valor de opción. El componente usa algunas de las características avanzadas de las aplicaciones controladas por modelos, como opciones de definiciones de columna (metadatos) y seguridad de nivel de columna.
Además de estas características, asegúrese de que el componente de código sigue las instrucciones de procedimientos recomendados:
- Uso de Microsoft Fluent UI para garantizar la coherencia y la accesibilidad.
- Localización de las etiquetas de componentes de código en el diseño y el tiempo de ejecución.
- Asegurarse de que el componente de código está controlado por metadatos para mejorar la reutilización.
- Garantizar que el componente de código se renderice de acuerdo con el factor de forma y el ancho disponible, mostrando una lista desplegable compacta con iconos cuando el espacio disponible es reducido.
Descargar el código de ejemplo ChoicesPicker
Puede descargar el ejemplo completo de PowerApps-Samples/component-framework/ChoicesPickerControl/.
Creación de un nuevo pcfproj proyecto
Nota:
Antes de empezar, asegúrese de instalar todos los componentes de requisitos previos.
Para crear un nuevo pcfproj proyecto:
Cree una nueva carpeta para contener el componente de código. Por ejemplo:
C:\repos\ChoicesPicker.Abra Visual Studio Code y vaya a Abrircarpetade archivos>. Seleccione la
ChoicesPickercarpeta que creó en el paso anterior. Si agregó las extensiones Windows Explorer durante la instalación de Visual Studio Code, también puede usar la opción de menú contextual Abrir con código dentro de la carpeta. También puede agregar cualquier carpeta a Visual Studio Code mediantecode .en el símbolo del sistema cuando el directorio actual esté establecido en esa ubicación.Dentro del nuevo terminal de PowerShell de Visual Studio Code (Terminal>nuevo terminal), use el comando pac pcf init para crear un nuevo proyecto de componente de código:
pac pcf init ` --namespace SampleNamespace ` --name ChoicesPicker ` --template field ` --run-npm-installo use el formato corto:
pac pcf init -ns SampleNamespace -n ChoicesPicker -t field -npm
En este paso se agregan archivos nuevos ChoicesPicker.pcfproj y relacionados a la carpeta actual, incluido un package.json que define los módulos necesarios. El comando anterior también ejecuta el npm install comando para instalar los módulos necesarios.
Running 'npm install' for you...
Nota:
Si recibe el error The term 'npm' is not recognized as the name of a cmdlet, function, script file, or operable program., asegúrese de instalar node.js (se recomienda la versión de LTS) y todos los demás requisitos previos.
Puede ver que la plantilla incluye un index.ts archivo junto con varios archivos de configuración. Este archivo es el punto de partida del componente de código y contiene los métodos de ciclo de vida descritos en Implementación de componentes.
Instalación de la interfaz de usuario de Microsoft Fluent
Usa Microsoft Fluent UI y React para crear la interfaz de usuario, así que instala estas dependencias. Para instalar las dependencias, use:
npm install react react-dom @fluentui/react
Este comando agrega los módulos al packages.json archivo e los instala en la node_modules carpeta . No agregue node_modules al control de código fuente, porque más adelante puede restaurar todos los módulos necesarios usando npm install.
Una ventaja de Microsoft Fluent UI es que proporciona una interfaz de usuario coherente y muy accesible.
Configuración de eslint
La plantilla usada por pac pcf init instala el módulo en el eslint proyecto y lo configura agregando un .eslintrc.json archivo. Debe configurar eslint para los estilos de código de TypeScript y React. Para obtener más información, consulte Configuración de ESLint para componentes de código.
Edición del manifiesto
El ChoicesPicker\ControlManifest.Input.xml archivo define los metadatos que describen el comportamiento del componente de código. Los atributos de control ya contienen el espacio de nombres y el nombre del componente.
Defina las siguientes propiedades vinculadas y de entrada:
| Nombre | Usage | Tipo | Description |
|---|---|---|---|
| Valor | bound |
OptionSet | Vincule esta propiedad a la columna de elección. El componente de código recibe el valor actual y, a continuación, notifica al contexto primario cuando cambia el valor. |
| Asignación de iconos | input |
Varias líneas de texto | Esta propiedad tendrá su valor establecido cuando el creador de la aplicación agregue el componente de código al formulario. Contiene una cadena JSON para configurar qué iconos se pueden usar para cada valor de opción. |
Para obtener más información, vea elemento property.
Sugerencia
Puede encontrar el XML más fácil de leer si lo formatea para que los atributos aparezcan en líneas separadas. Busque e instale una herramienta de formato XML de su elección en Marketplace de Visual Studio Code: Buscar extensiones de formato XML.
Los ejemplos a continuación se han formateado con atributos en líneas separadas para que sean más fáciles de leer.
Reemplazar el sampleProperty existente por las nuevas propiedades
ChoicesPicker\ControlManifest.Input.xml Abra y pegue las siguientes definiciones de propiedad dentro del elemento de control, reemplazando a la existentesampleProperty:
<property name="sampleProperty"
display-name-key="Property_Display_Key"
description-key="Property_Desc_Key"
of-type="SingleLine.Text"
usage="bound"
required="true" />
Guarde los cambios y, a continuación, use el siguiente comando para compilar el componente:
npm run build
Una vez compilado el componente, verá lo siguiente:
Se agrega un archivo
ChoicesPicker\generated\ManifestTypes.d.tsgenerado automáticamente al proyecto. El proceso de compilación genera este archivo a partir deControlManifest.Input.xmly proporciona los tipos para interactuar con las propiedades de entrada y salida.La salida de compilación se agrega a la
outcarpeta .bundle.jses el JavaScript transpilado que se ejecuta dentro del explorador. El archivoControlManifest.xmles una versión reformateada del archivoControlManifest.Input.xmlque se utiliza durante la implementación.Nota:
No modifique directamente el contenido de las
generatedcarpetas yout. El proceso de compilación los sobrescribe.
Implementación del componente ChoicesPicker Fluent UI React
Cuando el componente de código usa React, el updateView método debe representar un único componente raíz. Dentro de la ChoicesPicker carpeta , agregue un nuevo archivo TypeScript denominado ChoicesPickerComponent.tsxy agregue el siguiente contenido:
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';
Nota:
El archivo tiene la extensión tsx, un archivo TypeScript que admite la sintaxis de estilo XML usada por React. El proceso de compilación lo compila en JavaScript estándar.
Notas de diseño de ChoicesPickerComponent
En esta sección se incluyen comentarios sobre el diseño de ChoicesPickerComponent.
Es un componente funcional
Se trata de un componente funcional de React, pero también podría ser un componente de clase. Esto se basa en su estilo de codificación preferido. Los componentes de clase y los componentes funcionales también se pueden mezclar en el mismo proyecto. Tanto los componentes de función como de clase usan la tsx sintaxis de estilo XML usada por React. Más información: Componentes de función y clase
Minimizar el tamaño de bundle.js
Al importar los componentes de Fluent UI ChoiceGroup utilizando importaciones basadas en rutas, en lugar de:
import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react';
usamos:
import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react/lib/ChoiceGroup';
De este modo, el tamaño de la agrupación será menor, lo que dará lugar a requisitos de capacidad más bajos y un mejor rendimiento en tiempo de ejecución.
Una alternativa sería utilizar temblor de árboles.
Descripción de las "propiedades"
Las propiedades de entrada tienen los siguientes atributos proporcionados por index.ts en el updateView método :
prop |
Description |
|---|---|
label |
Se usa para etiquetar el componente. Esto está vinculado a la etiqueta del campo de metadatos que proporciona el contexto principal, utilizando el lenguaje de la interfaz de usuario seleccionado dentro de la aplicación basada en modelo. |
value |
Vinculado a la propiedad de entrada definida en el manifiesto. Esto puede ser NULL cuando el registro es nuevo o el campo no está establecido. TypeScript null se usa en lugar de undefined cuando se pasan o devuelven valores de propiedad. |
options |
Cuando un componente de código está enlazado a una columna de opciones de una aplicación controlada por modelos, la propiedad contiene el OptionMetadata que describe las opciones disponibles. Esto se pasa al componente para que pueda representar cada elemento. |
configuration |
El propósito del componente es mostrar un icono para cada opción disponible. El creador de la aplicación proporciona la configuración cuando agrega el componente de código a un formulario. Esta propiedad acepta una cadena JSON que asigna cada valor de opción numérico a un nombre de icono de la interfaz de usuario de Fluent. Por ejemplo: {"0":"ContactInfo","1":"Send","2":"Phone"}. |
onChange |
Cuando el usuario cambia la selección de opciones, el componente React desencadena el onChange evento. A continuación, el componente de código llama notifyOutputChanged a para que la aplicación controlada por modelos pueda actualizar la columna con el nuevo valor. |
Componente React controlado
Hay dos tipos de componentes de React:
| Tipo | Description |
|---|---|
| Descontrolado | Mantenga su estado interno y use las propiedades de entrada solo como valores predeterminados. |
| Controlado | Representa el valor pasado por las propiedades del componente. Si el evento onChange no actualiza los valores de las propiedades, el usuario no verá un cambio en la interfaz gráfica de usuario. |
ChoicesPickerComponent es un componente controlado, por lo que una vez que la aplicación controlada por modelos ha actualizado el valor (después de la notifyOutputChanged llamada), llama updateView al con el nuevo valor, que luego se pasa a las propiedades del componente, lo que provoca una nueva representación que muestra el valor actualizado.
Asignación de desestructuración
Asignación de la constante props: const { label, value, options, onChange, configuration } = props; usa la asignación por desestructuración. De esta forma, extrae los atributos requeridos para representar a partir de las propiedades, en lugar de prefijarlos con props cada vez que se utilizan.
Uso de componentes y enlaces de React
A continuación se explica cómo ChoicesPickerComponent.tsx se usan los componentes y enlaces de React:
| Elemento | Explanation |
|---|---|
| React.memo | Para encapsular nuestro componente funcional, para que no se represente a menos que alguna de las propiedades de entrada haya cambiado. |
| React.useMemo | Para asegurarse de que la matriz de elementos creada solo se muta cuando las propiedades options de entrada o configuration han cambiado. Este es un procedimiento recomendado para los componentes funcionales que reducirán las representaciones innecesarias de los componentes secundarios. |
| React.useCallback | Para crear un cierre de devolución de llamada que se llama cuando cambia de valor la Fluent UI ChoiceGroup. Este gancho de React asegura que el cierre de devolución de llamada solo se mute cuando el accesorio de entrada onChange está cambiado. Este es un procedimiento recomendado de rendimiento similar a useMemo. |
Comportamiento de error para la propiedad de entrada de la configuración
Si se produce un error en el análisis de la propiedad de entrada de configuración JSON, el error se representa mediante items.error.
Actualizar index.ts para representar el componente ChoicesPicker
Debe actualizar el archivo generado index.ts para renderizar el ChoicesPickerComponent.
Cuando se usa React dentro de un componente de código, el updateView método representa el componente raíz. Pasas al componente todos los valores necesarios para renderizarlo. Cuando estos valores cambian, el componente se vuelve a renderizar.
Agregar instrucciones de importación e inicializar iconos
Para poder usar el ChoicesPickerComponent componente en el index.ts archivo, agregue el código siguiente en la parte superior del archivo:
import { IInputs, IOutputs } from "./generated/ManifestTypes";
Nota:
Debe importar initializeIcons porque usa el conjunto de iconos de la interfaz de usuario de Fluent. Llame a initializeIcons para cargar los iconos en el entorno de pruebas. Dentro de las aplicaciones controladas por modelos, los iconos ya se inicializan.
Agregar atributos a la clase ChoicesPicker
El componente de código mantiene su estado de instancia mediante atributos. Este estado es diferente del estado del componente de React. Dentro del index.ts archivo, agregue los atributos siguientes a la ChoicesPicker clase :
export class ChoicesPicker implements ComponentFramework.StandardControl<IInputs, IOutputs> {
En la tabla siguiente se explican estos atributos:
| Atributo | Description |
|---|---|
notifyOutputChanged |
Contiene una referencia al método usado para notificar a la aplicación controlada por modelos que un usuario ha cambiado un valor de opción y el componente de código está listo para volver a pasarlo al contexto primario. |
rootContainer |
Elemento DOM HTML que se crea para contener el componente de código dentro de la aplicación controlada por modelos. |
selectedValue |
Contiene el estado de la opción seleccionada por el usuario para que se pueda devolver dentro del getOutputs método . |
context |
Contexto de Power Apps component framework que se utiliza para leer las propiedades definidas en el manifiesto y otras propiedades de runtime y métodos de API de acceso, como trackContainerResize. |
Actualización del init método
Para establecer estos atributos, actualice el init método .
public init(
context: ComponentFramework.Context<IInputs>,
notifyOutputChanged: () => void,
state: ComponentFramework.Dictionary,
container: HTMLDivElement):
void {
// Add control initialization code
}
El método init se llama cuando el componente de código se inicializa en una pantalla de la aplicación.
Adición del onChange método
Cuando el usuario cambia el valor seleccionado, llame notifyOutputChanged desde el onChange evento .
Agregue una función:
onChange = (newValue: number | undefined): void => {
this.selectedValue = newValue;
this.notifyOutputChanged();
};
Actualización del getOutputs método
public getOutputs(): IOutputs {
return {};
}
Sugerencia
Si antes escribió scripts de la API de cliente en aplicaciones basadas en modelos, puede que esté acostumbrado a usar el contexto del formulario para actualizar los valores de los atributos. Los componentes de código nunca deben tener acceso a este contexto. En su lugar, confíe en notifyOutputChanged y getOutputs para proporcionar uno o varios valores modificados. No es necesario devolver todas las propiedades enlazadas definidas en la IOutput interfaz, solo las que cambiaron su valor.
Actualización del updateView método
Actualice el método updateView para renderizar el ChoicesPickerComponent:
public updateView(context: ComponentFramework.Context<IInputs>): void {
// Add code to update control view
}
Obtienes la etiqueta y las opciones de context.parameters.value.
value.raw proporciona la opción numérica seleccionada o null si no se selecciona ningún valor.
Editar la función destroy
Limpie los recursos cuando se destruye el componente de código:
public destroy(): void {
// Add code to cleanup control if necessary
}
Para obtener más información, vea ReactDOM.unmountComponentAtNode.
Inicie la herramienta de ejecución de pruebas
Asegúrese de guardar todos los archivos. En el terminal, use:
npm start watch
Verá que el arnés de pruebas comienza con el selector de opciones representado dentro de una nueva ventana del explorador. Inicialmente, muestra un error porque la propiedad configuration string tiene el valor valpredeterminado . Establezca la configuración para que asocie las opciones predeterminadas del entorno de pruebas 0, 1 y 2 con los siguientes iconos de Fluent UI:
{"0":"ContactInfo","1":"Send","2":"Phone"}
Al cambiar la opción seleccionada, verá el valor en el panel Entradas de datos de la derecha. Si cambia el valor, el componente muestra el valor asociado actualizado.
Admite seguridad de solo lectura y seguridad a nivel de columna
Al crear componentes para aplicaciones basadas en modelos field, las aplicaciones deben respetar el estado del control cuando es de solo lectura o está enmascarado debido a la seguridad a nivel de columna. Si el componente de código no representa una interfaz de usuario de solo lectura cuando la columna es de solo lectura, en algunas circunstancias (por ejemplo, cuando un registro está inactivo), el usuario puede actualizar una columna donde no debería estar. Para obtener más información, consulte Seguridad de nivel de columna para controlar el acceso.
Editar el método updateView para la seguridad de solo lectura y de nivel de columna
En index.ts, edite el método updateView para agregar el siguiente código y obtener los indicadores disabled y 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 value.security propiedad solo está disponible en una aplicación controlada por modelos cuando se aplica la configuración de seguridad de nivel de columna a la columna enlazada.
Pasa estos valores al componente de React a través de sus props.
Edite ChoicesPickerComponent para agregar las propiedades deshabilitadas y enmascaradas
En ChoicesPickerComponent.tsx, acepte las disabled propiedades y masked agregándolas a la ChoicesPickerComponentProps interfaz :
export interface ChoicesPickerComponentProps {
label: string;
value: number | null;
options: ComponentFramework.PropertyHelper.OptionMetadata[];
configuration: string | null;
onChange: (newValue: number | undefined) => void;
}
Editar las propiedades del componente ChoicesPicker
Agregue los nuevos atributos a los props.
export const ChoicesPickerComponent = React.memo((props: ChoicesPickerComponentProps) => {
const { label, value, options, configuration, onChange } = props;
Editar el nodo de retorno de ChoicesPickerComponent
Dentro de ChoicesPickerComponent, al devolver los nodos de React, use estas nuevas propiedades de entrada para asegurarse de que el selector está deshabilitado o enmascarado.
return (
<>
{items.error}
<ChoiceGroup
label={label}
options={items.choices}
selectedKey={valueKey}
onChange={onChangeChoiceGroup}
/>
</>
);
Nota:
No debería ver diferencias en la herramienta de ejecución de pruebas porque no puede simular campos de solo lectura o seguridad a nivel de columna. Debe probar esta característica después de implementar el control dentro de una aplicación controlada por modelos.
Hacer que el componente de código responda
Los componentes de código pueden representarse en aplicaciones web, tabletas y móviles. Tenga en cuenta el espacio disponible. Haga que el componente de opciones se represente como una lista desplegable cuando el ancho disponible esté restringido.
Importar el componente de menú desplegable y los iconos
En ChoicesPickerComponent.tsx, el componente renderiza la versión pequeña mediante el componente Dropdown de Fluent UI, por lo que debes añadirlo a las importaciones:
import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react/lib/ChoiceGroup';
import * as React from 'react';
Agregar la propiedad formFactor
Actualice el componente de código para que se represente de forma diferente en función de una nueva propiedad formFactor. Agregue el atributo siguiente a la ChoicesPickerComponentProps interfaz :
export interface ChoicesPickerComponentProps {
label: string;
value: number | null;
options: ComponentFramework.PropertyHelper.OptionMetadata[];
configuration: string | null;
onChange: (newValue: number | undefined) => void;
disabled: boolean;
masked: boolean;
}
Agregar formFactor a las propiedades de 'ChoicesPickerComponent'
Agregue formFactor a las propiedades.
export const ChoicesPickerComponent = React.memo((props: ChoicesPickerComponentProps) => {
const { label, value, options, configuration, onChange, disabled, masked } = props;
Agregar métodos y modificar para dar soporte al componente desplegable
El componente desplegable necesita diferentes métodos de representación.
Agregue el código siguiente encima de
ChoicesPickerComponent: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 <></>; };Estos métodos permiten que
Dropdownmuestre el icono correcto junto al valor de la lista desplegable.Agregue un nuevo
onChangeDropDownmétodo.Agregue un
onChangemétodo para queDropdownsea similar al controlador deChoiceGroupeventos. Agregue la nuevaDropdownversión justo después del método existenteonChangeChoiceGroup:const onChangeDropDown = React.useCallback( (ev: unknown, option?: IDropdownOption): void => { onChange(option ? (option.data.value as number) : undefined); }, [onChange], );
Cambio de la salida representada
Realice los siguientes cambios para usar la nueva formFactor propiedad.
return (
<>
{items.error}
{masked && '****'}
{!items.error && !masked && (
<ChoiceGroup
label={label}
options={items.choices}
selectedKey={valueKey}
disabled={disabled}
onChange={onChangeChoiceGroup}
/>
)}
</>
);
Renderizas el componente ChoiceGroup cuando formFactor es grande y usas Dropdown cuando es pequeño.
Devolver DropdownOptions
Lo último que debe hacer en ChoicesPickerComponent.tsx es mapear los metadatos de las opciones de forma ligeramente distinta de la que utiliza ChoicesGroup. En el bloque de retorno items, debajo del elemento choices: options.map existente, añada el siguiente código:
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;
}),
};
Editar index.ts
Ahora que el componente de opciones se renderiza de forma diferente en función de la propiedad formFactor, pasa el valor correcto desde la llamada a renderizado dentro de index.ts.
Agregar las enumeraciones SmallFormFactorMaxWidth y FormFactors
Agregue el código siguiente justo antes de la export class ChoicesPicker clase dentro de index.ts.
const SmallFormFactorMaxWidth = 350;
const enum FormFactors {
Unknown = 0,
Desktop = 1,
Tablet = 2,
Phone = 3,
}
SmallFormFactorMaxWidth es el ancho cuando el componente comienza a representarse con el componente Dropdown en lugar del componente ChoiceGroup. La FormFactors enumeración se usa para mayor comodidad al llamar a context.client.getFormFactor.
Adición de código para detectar formFactor
Agregue el código siguiente a las React.createElement propiedades debajo de las propiedades existentes:
React.createElement(ChoicesPickerComponent, {
label: value.attributes.DisplayName,
options: value.attributes.Options,
configuration: configuration.raw,
value: value.raw,
onChange: this.onChange,
disabled: disabled,
masked: masked,
}),
Solicitud de actualizaciones para cambiar el tamaño
Dado que usa context.mode.allocatedWidth, debe permitir que la aplicación controlada por modelos sepa que desea recibir actualizaciones (a través de una llamada a updateView) cuando cambie el ancho disponible. Agregue una llamada a context.mode.trackContainerResize dentro del init método :
public init(
context: ComponentFramework.Context<IInputs>,
notifyOutputChanged: () => void,
state: ComponentFramework.Dictionary,
container: HTMLDivElement):
void {
this.notifyOutputChanged = notifyOutputChanged;
this.rootContainer = container;
this.context = context;
}
Probar la herramienta ejecución de pruebas
Guarde todos los cambios para que la ventana del explorador del arnés de pruebas los refleje automáticamente. Mantén npm start watch en ejecución desde antes. Cambie el valor de Ancho de contenedor de componentes entre 349 y 350 y vea que la representación se comporta de forma diferente. Cambie el factor de forma entre Web y Phone y vea el mismo comportamiento.
Localización
Para admitir varios lenguajes, el componente de código puede incluir un archivo de recursos que proporcione traducciones para cadenas de diseño y en tiempo de ejecución.
Agregue un nuevo archivo en la ubicación
ChoicesPicker\strings\ChoicesPicker.1033.resx. Para añadir etiquetas para una configuración regional diferente, cambie 1033 (en-us) por la configuración regional que elija.Con el editor de recursos Visual Studio Code, escriba los siguientes valores:
Nombre Importancia ChoicesPicker_NameSelector de opciones (controlado por modelos) ChoicesPicker_DescMuestra las opciones como selector con iconos Value_NameImportancia Value_DescCampo de opciones al que se va a enlazar el control Configuration_NameConfiguración de asignación de iconos Configuration_DescConfiguración que asigna el valor de elección a un icono de Fluent UI. Por ejemplo, {"1":"ContactInfo","2":"Send"} De lo contrario, establezca el contenido del archivo .resx con el siguiente XML:
<?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>Sugerencia
No edite
resxarchivos directamente. El editor de recursos Visual Studio Code o una extensión para Visual Studio Code facilita esta tarea.
Actualizar el manifiesto para las cadenas de recursos
Después de crear las cadenas de recursos, actualice ControlManifest.Input.xml para que haga referencia a ellas.
<?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>
Puede ver lo siguiente:
- Los
display-name-keyydescription-keyahora apuntan a la clave correspondiente en el archivoresx. - Hay una entrada adicional en el
resourceselemento que indica que el componente de código debe cargar recursos desde el archivo al que se hace referencia.
Si necesita más cadenas para su uso en el componente, agréguelas al resx archivo y, a continuación, cargue las cadenas en tiempo de ejecución mediante getString. Para obtener más información, consulte Implementación del componente de API de localización.
Nota:
Una limitación del arnés de pruebas es que no carga archivos de recursos. Para probar completamente el componente, debe implementar el componente en Microsoft Dataverse.
Implementación y configuración en una aplicación controlada por modelos
Después de probar la funcionalidad básica con el arnés de pruebas, implemente el componente en Microsoft Dataverse para que pueda probar completamente el componente de código de un extremo a otro dentro de una aplicación controlada por modelos.
Dentro del entorno de Dataverse, asegúrese de que hay un publicador creado con un prefijo de
samples:
También puede usar su propio publicador, siempre que actualice el parámetro de prefijo del publicador en la llamada a pac pcf push en consecuencia.
Para más información, consulte Creación de un publicador de soluciones.
Después de guardar el publicador, autorice la CLI de Microsoft Power Platform en su entorno para que pueda insertar el componente de código compilado. En la línea de comandos, use:
pac auth create --url https://myorg.crm.dynamics.comReemplace por
myorg.crm.dynamics.comla dirección URL del entorno de Dataverse. Inicie sesión con privilegios de administrador o personalizador del sistema cuando se le solicite. Estos roles proporcionan los privilegios necesarios para implementar los componentes de código en Dataverse.Para implementar el componente de código, use:
pac pcf push --publisher-prefix samplesNota:
Si recibe el error
Missing required tool: MSBuild.exe/dotnet.exe, agregueMSBuild.exe/dotnet.exeen la variable de entorno Path o useDeveloper Command Prompt for Visual Studio Code. Debe instalar Visual Studio 2019 para Windows y Mac o Herramientas de compilación para Visual Studio 2019. Asegúrese de seleccionar la carga de trabajo.NET build toolstal como se describe en los requisitos previos.Cuando finaliza el proceso, crea una solución temporal denominada PowerAppTools_samples en el entorno. El
ChoicesPickercomponente de código se agrega a esta solución. Puede mover el componente de código a la solución más adelante si es necesario. Para obtener más información, consulte Administración del ciclo de vida de las aplicaciones de componentes de código (ALM).
A continuación, agregue el componente de código al formulario Contactos y, para ello, vaya a Formulario principal en el Editor clásico, seleccionando Método de contacto preferido>>>Agregar control>Selector de opciones>Agregar.
Nota:
En el futuro, no necesitará el editor clásico para configurar componentes de código en formularios de aplicaciones controladas por modelos.
Establezca las siguientes propiedades en el componente:
Establezca el Selector de opciones como valor predeterminado para web, teléfono y tableta.
Escriba la siguiente cadena para la Configuración de Asignación de Iconos, seleccionando el icono de edición y luego Enlazar a un valor estático.
{ "1":"ContactInfo", "2":"Send", "3":"Phone", "4":"Fax", "5":"DeliveryTruck" }Estos iconos de la interfaz de usuario de Fluent se usan para cada valor de opción.
Seleccione la pestaña Mostrar y desactive Mostrar etiqueta en el formulario , ya que muestra la etiqueta encima del selector de opciones.
Guarde y publique el formulario.
Abra un registro de contacto dentro de la aplicación controlada por modelos con el formulario correcto seleccionado. Verá el componente de código
ChoicesPickeren lugar del control desplegable estándar. (Es posible que tenga que realizar una recarga difícil de la página para que se muestre el componente).Nota:
Es posible que vea que la alineación del texto es ligeramente diferente en el arnés de prueba en comparación con las aplicaciones controladas por modelos. Esta diferencia se produce porque el arnés de pruebas tiene reglas CSS diferentes a las aplicaciones controladas por modelos. Por este motivo, siempre pruebe completamente el componente de código después de la implementación.
Depurar después de implementar en Dataverse
Si necesita realizar más cambios en el componente, no es necesario implementarlos cada vez. En su lugar, utilice la técnica descrita en Componentes del código de depuración para crear un Fiddler AutoResponder para cargar el archivo desde su sistema de archivos local mientras se ejecuta npm start watch.
Nota:
Es posible que no tenga que depurar después de la implementación en Dataverse si puede probar toda la funcionalidad mediante el arnés de pruebas. Sin embargo, implemente y pruebe siempre en Dataverse antes de distribuir el componente de código.
AutoResponder tiene un aspecto similar al siguiente:
REGEX:(.*?)((?'folder'css|html)(%252f|\/))?SampleNamespace\.ChoicesPicker[\.\/](?'fname'[^?]*\.*)(.*?)$
C:\repos\ChoicesPicker\out\controls\ChoicesPicker\${folder}\${fname}
Necesitará Caché vacío y actualización completa en la sesión de su navegador para que el archivo AutoResponder sea recogido. Una vez cargado, puede actualizar el explorador, ya que Fiddler agrega un encabezado de control de caché al archivo para evitar que se almacene en caché.
Cuando haya terminado con los cambios, puede incrementar la versión de parche en el manifiesto y luego volver a desplegar con pac pcf push.
Hasta ahora, ha implementado una compilación de desarrollo que no está optimizada y se ejecuta más lentamente en tiempo de ejecución. Puede optar por implementar una compilación optimizada mediante pac pcf push después de editar el ChoicesPicker.pcfproj archivo. Debajo de OutputPath, agregue lo siguiente:
<PcfBuildMode>production</PcfBuildMode>
Artículos relacionados
Administración del ciclo de vida de las aplicaciones (ALM) con Microsoft Power Platform
Referencia de la API del framework de componentes de Power Apps
Crear el primer componente
Depurar componentes de código