Tutorial: Crear un componente de campo de aplicación basado en modelo
En este tutorial, creará un componente de aplicación basada en modelo field
, lo implementará, configurará y probará el componente en un formulario usando Visual Studio Code. Este componente de código muestra un conjunto de opciones en el formulario con un icono al lado de cada valor de elección. El componente utiliza algunas de las funciones avanzadas de las aplicaciones basadas en modelos, como definiciones de columnas de opciones (metadatos) y seguridad a nivel de columna.
Además de estos, también se asegurará de que el componente de código siga la guía de prácticas recomendadas:
- Uso de Interfaz de usuario Microsoft Fluent para coherencia y accesibilidad
- Localización de las etiquetas de los componentes de código tanto en el diseño como en el runtime
- Asegurarse de que el componente de código esté basado en metadatos para una mejor reutilización
- Asegurarse de que el componente de código se representa de acuerdo con el factor de forma y el ancho disponible, mostrando un desplegable compacto con iconos en el que el espacio es limitado
Código
Puede descargar el ejemplo completo en PowerApps-Samples/component-framework/ChoicesPickerControl/.
Crea un nuevo proyecto pcfproj
Nota
Antes de comenzar, asegúrese de haber instalado todos los componentes de los requisitos previos.
Para crear un nuevo pcfproj
:
Cree una nueva carpeta para contener su componente de código. Por ejemplo,
C:\repos\ChoicesPicker
.Abra Visual Studio Code y vaya a Archivo > Abrir carpeta y seleccione la carpeta
ChoicesPicker
creada en el paso anterior. Si ha agregado las extensiones del Explorador de Windows durante la instalación de Visual Studio Code, también puede utilizar la opción del menú contextual Abrir con Code dentro de la carpeta. También puede agregar cualquier carpeta en Visual Studio Code usandocode .
en el símbolo del sistema cuando el directorio actual se establece en esa ubicación.Dentro de la terminal de PowerShell Visual Studio Code (Terminal > Nueva 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-install
o usando la forma corta:
pac pcf init -ns SampleNamespace -n ChoicesPicker -t field -npm
Esto agrega un nuevo ChoicesPicker.pcfproj
y archivos relacionados a la carpeta actual, incluyendo un package.json
que define los módulos necesarios. El comando anterior también ejecutará el comando npm install
para que instale 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 haber instalado todos los requisitos previos, específicamente node.js (Se recomienda la versión LTS) y el resto de prerrequisitos.
Puede ver que la plantilla incluye un archivo index.ts
junto con varios archivos de configuración. Este es el punto de partida de su componente de código y contiene los métodos de ciclo de vida descritos en Implementación de componentes.
Instalar Interfaz de usuario fluida de Microsoft
Utilizará Microsoft Fluent UI y React para crear interfaces de usuario, por lo que debe instalarlos como dependencias. Para instalar las dependencias, use:
npm install react react-dom @fluentui/react
Esto agrega los módulos a packages.json
y los instala en la carpeta node_modules
. No comprometerá node_modules
en control de fuente ya que todos los módulos requeridos se restaurarán más tarde usando npm install
.
Una de las ventajas de Microsoft Fluent UI es que proporciona una IU coherente y muy accesible.
Configurando eslint
La plantilla utilizada por pac pcf init instala el módulo eslint
a su proyecto y lo configura agregando un archivo .eslintrc.json
. Eslint
requiere la configuración para los estilos de codificación TypeScript y React. Más información: Linting: mejores prácticas y orientación para componentes de código.
Editar el manifiesto
El archivo ChoicesPicker\ControlManifest.Input.xml
define los metadatos que describen el comportamiento del componente de código. Los atributos de control ya tienen el espacio de nombres y el nombre de su componente.
Debe definir las siguientes propiedades bound e input:
Name | Uso | Type | Descripción |
---|---|---|---|
valor | bound |
OptionSet | Esta propiedad estará vinculada a la columna de opción. El componente de código recibe el valor actual y luego notifica al contexto principal cuando el valor ha cambiado. |
Asignación de iconos | input |
Varias líneas de texto | Esta propiedad tendrá su valor establecido cuando el creador de aplicaciones agregue el componente de código al formulario. Contiene una cadena JSON para configurar qué iconos pueden usarse para cada valor de elección. |
Más información: elemento de propiedad.
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 Visual Studio Code Marketplace: 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 con propiedades nuevas
Abra ChoicesPicker\ControlManifest.Input.xml
y pegue lo siguiente dentro del elemento de control (reemplazando el existente sampleProperty
):
<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 luego use el siguiente comando para compilar el componente:
npm run build
Una vez creado el componente, verá que:
Un archivo generado automáticamente
ChoicesPicker\generated\ManifestTypes.d.ts
se agrega a su proyecto. Esto se genera como parte del proceso de construcción desdeControlManifest.Input.xml
y proporciona los tipos para interactuar con las propiedades de entrada / salida.La salida de la compilación se agrega a la carpeta
out
.bundle.js
es el JavaScript transpilado que se ejecuta dentro del navegador.ControlManifest.xml
es una versión reformateada del archivoControlManifest.Input.xml
que se utiliza durante la implementación.Nota
No modifique el contenido de las carpetas
generated
yout
directamente. Se sobrescribirán como parte del proceso de compilación.
Implementar el componente de reacción de la interfaz de usuario Fluent ChoicesPicker
Cuando el componente de código usa React, debe haber un solo componente raíz que se representa dentro del método updateView
. Dentro de la carpeta ChoicesPicker
, agregue un nuevo archivo TypeScript llamado ChoicesPickerComponent.tsx
y 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 utilizada por React. Se compila en JavaScript estándar mediante el proceso de compilación.
Notas de diseño de ChoicesPickerComponent
Esta sección incluye comentarios en el diseño de ChoicesPickerComponent
.
Es un componente funcional
Este es un componente funcional de React, pero igualmente 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 utilizan la sintaxis de estilo tsx
XML utilizada por React. Más información: Componentes funcionales y de clase
Minimizar el tamaño de bundle.js
Al importar los componentes de la UI de Fluent 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 esta forma, el tamaño del paquete será más pequeño, lo que dará como resultado 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 que serán proporcionados por index.ts
en el método updateView
:
prop |
Descripción |
---|---|
label |
Se utiliza 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 nulo cuando el registro es nuevo o el campo no está configurado. TypeScript null se usa en lugar de undefined al pasar / devolver valores de propiedad. |
options |
Cuando un componente de código está vinculado a una columna de opciones en una aplicación basada en modelo, la propiedad contiene la OptionMetadata que describe las opciones disponibles. Pasa esto al componente para que pueda representar cada elemento. |
configuration |
El propósito del componente es mostrar un icono para cada opción disponible. La configuración la proporciona el creador de la aplicación cuando agrega el componente de código a un formulario. Esta propiedad acepta una cadena JSON que asigna cada valor de elección numérica a un nombre de icono de la interfaz de usuario Fluent. Por ejemplo, {"0":"ContactInfo","1":"Send","2":"Phone"} . |
onChange |
Cuando el usuario cambia la selección de opciones, el componente React activa el evento onChange . El componente de código luego llama a notifyOutputChanged para que la aplicación basada en modelos pueda actualizar la columna con el nuevo valor. |
Componente React controlado
Existen dos tipos de componentes React:
Type | Descripción |
---|---|
Sin control | Mantiene su estado interno y usan los accesorios de entrada solo como valores predeterminados. |
Controlado | Representa el valor pasado por las propiedades del componente. Si el evento onChange no actualiza los valores del accesorio, el usuario no verá un cambio en la interfaz de usuario. |
ChoicesPickerComponent
es un componente controlado, por lo que una vez que la aplicación basada en modelo ha actualizado el valor (después de la llamada notifyOutputChanged
), llama al updateView
con el nuevo valor, que luego se pasa a los accesorios del componente, lo que provoca una nueva representación que muestra el valor actualizado.
Asignación de desestructuración
La asignación de la constante props
: const { label, value, options, onChange, configuration } = props;
usa la asignación de 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
utiliza los componentes y enlaces de React:
Item | Explicación |
---|---|
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 garantizar que la matriz de elementos creada solo se mute cuando los accesorios de entrada options o configuration cambian. Es un procedimiento recomendado para componentes funcionales que reducirá 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 interfaz de usuario Fluent 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. Esta es una práctica recomendada de rendimiento similar a useMemo . |
Comportamiento de error para la propiedad de entrada de la configuración
Si el análisis de la propiedad de entrada de la configuración JSON falla, el error se representa usando items.error
.
Actualizar index.ts para representar el componente ChoicesPicker
Debe actualizar el index.ts file
generado para representar ChoicesPickerComponent.
Cuando se usa React dentro de un componente de código, la representación del componente raíz se realiza dentro del método updateView
. Todos los valores necesarios para representar el componente se pasan al componente, como cuando se cambian, y luego se vuelve a representar.
Agregar instrucciones de importación e inicializar iconos
Antes de que pueda utilizar ChoicesPickerComponent
en index.ts
, debe agregar lo siguiente en la parte superior del archivo:
Nota
La importación de initializeIcons
es obligatoria porque está utilizando el conjunto de iconos de Fluent UI. Debe llamar a initializeIcons
para cargar los iconos dentro del arnés de prueba. Dentro de las aplicaciones basadas en modelos, ya están inicializados.
Agregar atributos a la clase ChoicesPicker
El componente de código mantiene su estado de instancia mediante atributos. (Esto es diferente al estado del componente React). Dentro de la clase index.ts
ChoicesPicker
, agregue los atributos siguientes:
export class ChoicesPicker implements ComponentFramework.StandardControl<IInputs, IOutputs> {
En la siguiente tabla, se describen estos atributos:
Attribute | Descripción |
---|---|
notifyOutputChanged |
Contiene una referencia al método utilizado para notificar a la aplicación basada en modelos que un usuario ha cambiado un valor de elección y el componente de código está listo para devolverlo al contexto principal. |
rootContainer |
Elemento DOM HTML que se crea para contener el componente de código dentro de la aplicación basada en modelo. |
selectedValue |
Mantiene el estado de la elección seleccionada por el usuario para que pueda ser devuelto dentro del método getOutputs . |
context |
El contexto de Power Apps component framework que se utiliza para leer las propiedades definidas en el manifiesto y otras propiedades del entorno de tiempo de ejecución y métodos de API de acceso, como trackContainerResize . |
Actualizar el método init
Para configurar estos atributos, actualice el método init
.
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 la pantalla de una aplicación.
Agregar el método onChange
Cuando el usuario cambia el valor seleccionado, debe llamar a notifyOutputChanged
desde el evento onChange
.
Agregar una función:
onChange = (newValue: number | undefined): void => {
this.selectedValue = newValue;
this.notifyOutputChanged();
};
Actualizar el método getOutputs
Sugerencia
Si ha escrito scripts de API de cliente antes en aplicaciones basadas en modelos, es posible que esté acostumbrado a usar el contexto del formulario para actualizar los valores de los atributos. Los componentes de código nunca deben acceder a este contexto. En cambio, confíe en notifyOutputChanged
y getOutputs
para proporcionar uno o más valores modificados. No es necesario que devuelva todas las propiedades enlazadas definidas en la interfaz IOutput
, sino solo las que han cambiado de valor.
Actualizar el método updateView
Ahora, actualice updateView
para representar el ChoicesPickerComponent
:
public updateView(context: ComponentFramework.Context<IInputs>): void {
// Add code to update control view
}
Observe que está extrayendo la etiqueta y las opciones de context.parameters.value
, y el value.raw
proporciona la opción numérica seleccionada, o null
si no se selecciona ningún valor.
Editar la función destroy
Por último, debe ordenar cuando se destruye el componente de código:
Más información: ReactDOM.unmountComponentAtNode
Inicie la herramienta de ejecución de pruebas
Asegúrese de que todos los archivos estén guardados y en el terminal use:
npm start watch
Verá que la herramienta de ejecución de pruebas comienza con el selector de opciones representado dentro de una nueva ventana del navegador. Inicialmente, muestra un error porque la propiedad de la cadena configuration
tiene el valor predeterminado val
. Establezca la configuración para que asigne las opciones predeterminadas de la herramienta de ejecución de pruebas 0,1 y 2 con los siguientes iconos de interfaz de usuario de Fluent:
{"0":"ContactInfo","1":"Send","2":"Phone"}
Cuando cambie la opción seleccionada, verá el valor en el panel Entradas de datos de la derecha. Además, si cambia el valor, el componente muestra el valor asociado actualizado.
Compatibilidad con la seguridad de solo lectura y de nivel de columna
Al crear componentes field
para aplicaciones basadas en modelo, las aplicaciones deben respetar el estado de control cuando son de solo lectura o enmascaradas debido a la seguridad a nivel de columna. Si el componente de código no representa una IU 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 ser. Más información: Seguridad a nivel de columna para controlar el acceso.
Editar el método updateView para seguridad de solo lectura y de nivel de columna
En index.ts
, edite el método updateView
para agregar el siguiente código para obtener las marcas 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,
);
}
}
value.security
se completará solo dentro de una aplicación basada en modelo si se aplica la configuración de seguridad a nivel de columna a la columna enlazada.
Estos valores luego se pueden pasar al componente React a través de sus propiedades.
Editar ChoicesPickerComponent para agregar las propiedades deshabilitadas y enmascaradas
En ChoicesPickerComponent.tsx
, puede aceptar las propiedades disabled
y masked
agregándolass a la interfaz ChoicesPickerComponentProps
:
export interface ChoicesPickerComponentProps {
label: string;
value: number | null;
options: ComponentFramework.PropertyHelper.OptionMetadata[];
configuration: string | null;
onChange: (newValue: number | undefined) => void;
}
Editar las propiedades ChoicesPickerComponent
Agregue los nuevos atributos a las propiedades.
export const ChoicesPickerComponent = React.memo((props: ChoicesPickerComponentProps) => {
const { label, value, options, configuration, onChange } = props;
Editar el nodo de devolución ChoicesPickerComponent
En ChoicesPickerComponent
al devolver los nodos de React, puede usar estos nuevos accesorios 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. Deberá probar esto después de implementar el control dentro de una aplicación basada en modelo.
Hacer que el componente de código sea receptivo
Los componentes de código se pueden renderizar en aplicaciones web, tabletas y móviles. Es importante considerar el espacio disponible. Haga que el componente de opciones se represente como un menú desplegable cuando el ancho disponible esté restringido.
Importar el componente desplegable y los iconos
En ChoicesPickerComponent.tsx
, el componente representa la versión pequeña usando el componente Dropdown
de la IU Fluent, por lo que lo agrega a las importaciones:
import { ChoiceGroup, IChoiceGroupOption } from '@fluentui/react/lib/ChoiceGroup';
import * as React from 'react';
Agregar la prop formFactor
Actualice el componente de código para representar de manera diferente dependiendo de una nueva prop formFactor
. Agregue el atributo siguietne a la interfaz 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;
}
Agregar formFactor a las propiedades ChoicesPickerComponent
Agregar 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 admitir el componente desplegable
El componente desplegable necesita algunos métodos de representación diferentes.
Encima de
ChoicesPickerComponent
, agregue lo siguiente: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 serán utilizados por
Dropdown
para representar el icono correcto junto al valor desplegable.Agregue un nuevo método de
onChangeDropDown
.También necesitamos un método
onChange
paraDropdown
, similar al controlador de eventosChoiceGroup
. Justo debajo delonChangeChoiceGroup
existente, agregue la nueva versiónDropdown
:const onChangeDropDown = React.useCallback( (ev: unknown, option?: IDropdownOption): void => { onChange(option ? (option.data.value as number) : undefined); }, [onChange], );
Cambiar la salida renderizada
Realizar los cambios siguientes para utilizar la propiedad formFactor
nueva.
return (
<>
{items.error}
{masked && '****'}
{!items.error && !masked && (
<ChoiceGroup
label={label}
options={items.choices}
selectedKey={valueKey}
disabled={disabled}
onChange={onChangeChoiceGroup}
/>
)}
</>
);
Puede ver que genera el componente ChoiceGroup
cuando formFactor
es grande y usa Dropdown
cuando es pequeño.
Devolver DropdownOptions
El último paso en ChoicesPickerComponent.tsx
es asignar los metadatos de las opciones de forma ligeramente diferente a la que utiliza el ChoicesGroup
, así que dentro del bloque de devolución items
, debajo de las choices
existentes: options.map
, agregue lo siguiente:
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 renderizará de manera diferente según el accesorio formFactor
, debe pasar el valor correcto de la llamada de renderización dentro de index.ts
.
Agregar las enumeraciones SmallFormFactorMaxWidth y FormFactors
Agregue lo siguiente justo encima de la clase export class ChoicesPicker
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 renderizarse usando Dropdown
en vez del componente ChoiceGroup
. FormFactors
enum
se utiliza por conveniencia al llamar context.client.getFormFactor
.
Agregar código para detectar formFactor
Agregue lo siguiente a los accesorios React.createElement
debajo de los accesorios 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,
}),
Solicitar actualizaciones para cambiar el tamaño
Ya que está usando context.mode.allocatedWidth
, debe informar a la aplicación basada en modelo que desea recibir actualizaciones (a través de una llamada a updateView
) cuando cambia el ancho disponible. Hace esto dentro del método init
agregando una llamada a 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;
}
Probar la herramienta ejecución de pruebas
Ahora guarde todos los cambios, para que se reflejen automáticamente en la ventana del navegador de la herramienta de ejecución de pruebas (porque todavía tiene npm start watch
ejecutándose desde antes). Ahora puede cambiar el valor de Ancho del contenedor de componentes entre 349 y 350 y ver cómo el renderizado se comporta de manera diferente. También puede intercambiar el Factor de forma entre Web y Teléfono y ver el mismo comportamiento.
Localización
Si desea admitir varios idiomas, su componente de código puede contener un archivo de recursos que proporciona traducciones tanto para el diseño como para las cadenas de tiempo de ejecución.
Agregue un nuevo archivo en la ubicación
ChoicesPicker\strings\ChoicesPicker.1033.resx
. Si desea agregar etiquetas para una configuración regional diferente, cambie el 1033 (en-us
) al lugar que elija.Usando el editor de recursos de Visual Studio Code, escriba lo siguiente:
Name valor ChoicesPicker_Name
Selector de opciones (basado en modelos) ChoicesPicker_Desc
Muestra opciones como un selector con iconos Value_Name
valor Value_Desc
El campo de opciones al que vincular el control Configuration_Name
Configuración de la asignación de iconos Configuration_Desc
Configuración que asigna el valor de elección a un icono de interfaz de usuario fluida. Por ejemplo, {"1":"ContactInfo","2":"Send"} De lo contrario, configure 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 se recomienda editar archivos
resx
directamente. El editor de recursos de Visual Studio Code o una extensión para Visual Studio Code lo facilita.
Actualizar el manifiesto para las cadenas de recursos
Ahora que tiene las cadenas de recursos, puede hacer referencia a ellas actualizando el ControlManifest.Input.xml
como sigue:
<?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 que:
- Los valores
display-name-key
ydescription-key
ahora apuntan a la clave correspondiente en el archivoresx
. - Hay una entrada adicional en el elemento
resources
que indica que el componente de código debe cargar recursos desde el archivo referenciado.
Si necesita cadenas adicionales para usar en su componente, puede agregarlas al resx
y luego cargue las cadenas en tiempo de ejecución usando getString. Más información: Implementación del componente de API de localización.
Nota
Una de las limitaciones de la herramienta de ejecución de pruebas es que no carga archivos de recursos, por lo que debe implementar el componente para Microsoft Dataverse para probar completamente su componente.
Implementar y configurar en una aplicación basada en modelos
Una vez que haya probado la funcionalidad básica con la herramienta de ejecución de pruebas, debe implementar el componente en Microsoft Dataverse para que el componente de código pueda probarse completamente de un extremo a otro dentro de una aplicación basada en modelo.
Dentro de su entorno de Dataverse, asegúrese de que haya un editor creado con un prefijo de
samples
:Del mismo modo, este podría ser su editor, siempre que actualice el parámetro de prefijo del editor en la llamada a pac pcf push a continuación. Más información: Crear un editor de soluciones.
Una vez que haya guardado el editor, estará listo para autorizar la Microsoft Power Platform CLI en su entorno para que pueda enviar el componente de código compilado. En la línea de comandos, use:
pac auth create --url https://myorg.crm.dynamics.com
Reemplace
myorg.crm.dynamics.com
con la URL de su entorno de Dataverse. Inicie sesión con un Administrador del sistema o privilegios de personalizador cuando se le solicite. Los privilegios proporcionados por estos roles son necesarios para implementar cualquier componente de código en Dataverse.Para implementar su componente de código, use:
pac pcf push --publisher-prefix samples
Nota
Si recibe el error
Missing required tool: MSBuild.exe/dotnet.exe
, agregueMSBuild.exe/dotnet.exe
en la variable de entorno de ruta o useDeveloper Command Prompt for Visual Studio Code
. Debe instalar Visual Studio 2019 para Windows y Mac o Crear herramientas para Visual Studio 2019. Asegúrese de seleccionar la carga de trabajo.NET build tools
como se describe en los requisitos previos.Una vez completado, este proceso crea una solución temporal llamada PowerAppTools_samples en su entorno. El componente de código
ChoicesPicker
se agregará a esta solución. Puede mover el componente de código a su solución más adelante si es necesario. Más información: Componente de código de Administración del ciclo de vida de las aplicaciones (ALM).A continuación, agregue el componente de código al formulario Contactos yendo a Formulario principal en el Editor clásico, seleccione Método de contacto preferido > Cambiar propiedades > Pestaña controles > Agregar control > Seleccionar selector de opciones > Agregar.
Nota
En el futuro, no se 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:
Configure el Selector de opciones como predeterminado para la Web, teléfono y tableta.
Introduzca la siguiente cadena para la Configuración de asignación de iconos seleccionando el icono de edición y seleccionando Enlazar a un valor estático.
{ "1":"ContactInfo", "2":"Send", "3":"Phone", "4":"Fax", "5":"DeliveryTruck" }
Estos son los íconos de la interfaz de usuario Fluent que se utilizarán para cada valor de elección.
Seleccione la Pestaña de visualización y desmarque Mostrar etiqueta en el formulario, ya que mostrará la etiqueta sobre el selector de opciones.
Guarde y Publique el formulario.
Abra un registro de contacto dentro de la aplicación basada en modelos con el formulario correcto seleccionado. Ahora verá el componente de código
ChoicesPicker
en lugar del control desplegable estándar. (Es posible que deba realizar una recarga completa de la página para que aparezca el componente).Nota
Puede ver que la alineación del texto es ligeramente diferente en la herramienta de ejecución de pruebas en comparación con las aplicaciones basadas en modelos. Esto se debe a que el arnés de prueba tiene reglas CSS diferentes a las de las aplicaciones basadas en modelos. Por esta razón, se recomienda que siempre pruebe completamente su componente de código después de la implementación.
Depurar después de implementar a Dataverse
Si necesita realizar más cambios en su componente, no necesita implementarlo 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 necesite depurar después de la implementación en Dataverse si toda la funcionalidad se puede probar usando el arnés de prueba. Sin embargo, se recomienda siempre implementar y probar dentro de Dataverse antes de distribuir su componente de código.
La Respuesta automática se vería similar a lo 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 Respuesta automática sea recogido. Una vez cargado, puede actualizar el navegador, ya que Fiddler agregará un encabezado de control de caché al archivo para evitar que se almacene en caché.
Una vez que ahya terminado sus cambios, puede incrementar la versión del parche en el manifiesto y luego volver a implementar usando pac pcf push..
Hasta ahora, ha implementado una compilación de desarrollo, que no está optimizada y se ejecutará más lentamente en tiempo de ejecución. Puede optar por implementar una compilación optimizada utilizando pac pcf push editando el ChoicesPicker.pcfproj
. Debajo de OutputPath
, agregue lo siguiente:
<PcfBuildMode>production</PcfBuildMode>
Artículos relacionados
Administración del ciclo de vida de la aplicación (ALM) con Microsoft Power Platform
Referencia de la API de Power Apps component framework
Crear el primer componente
Depurar componentes de código
Nota
¿Puede indicarnos sus preferencias de idioma de documentación? Realice una breve encuesta. (tenga en cuenta que esta encuesta está en inglés)
La encuesta durará unos siete minutos. No se recopilan datos personales (declaración de privacidad).