Compartir a través de


Migrar de JSLink a Extensiones de SharePoint Framework

Desde Microsoft SharePoint 2013, la mayoría de las soluciones empresariales creadas con Microsoft 365 y SharePoint Online han aprovechado la propiedad JSLink de campos y vistas de lista para personalizar la representación de campos.

Dentro de la interfaz de usuario "moderna" de SharePoint Online y SharePoint Server 2019, la mayoría de esas personalizaciones ya no están disponibles. Afortunadamente, las extensiones de SharePoint Framework permiten proporcionar una funcionalidad similar en la interfaz de usuario "moderna".

En este tutorial, obtendrá información sobre cómo migrar de las anteriores personalizaciones "clásicas" al nuevo modelo basado en extensiones de SharePoint Framework.

Nota:

Para más información sobre cómo compilar extensiones de SharePoint Framework, Consulte Información general de extensiones de SharePoint Framework.

En primer lugar, se presentan las opciones disponibles al desarrollar extensiones de SharePoint Framework:

La opción más útil en nuestro contexto es la extensión de personalizador de campo.

Supongamos que está en SharePoint Online y que tiene una lista personalizada con un campo personalizado denominado "Color", que es de tipo Choice y que puede asumir los siguientes valores: Rojo, Verde, Azul, Amarillo. Supongamos que tiene un valor personalizado para la JSLink propiedad del elemento web de representación de vista de lista de la lista personalizada.

En el siguiente fragmento de código, puede ver el código JavaScript al que hace referencia la propiedad JSLink (customColorRendering.js).

// Define a namespace for the custom rendering code
var customJSLinkRendering = customJSLinkRendering || {};

// Define a function that declare the custom rendering rules for the target list view
customJSLinkRendering.CustomizeFieldRendering = function () {

  // Define a custom object to configure the rendering template overrides
  var customRenderingOverride = {};
  customRenderingOverride.Templates = {};
  customRenderingOverride.Templates.Fields =
  {
    // Declare the custom rendering function for the 'View' of field 'Color'
    'Color':
    {
      'View': customJSLinkRendering.RenderColorField
    }
  };

  // Register the custom rendering template
  SPClientTemplates.TemplateManager.RegisterTemplateOverrides(customRenderingOverride);
};

// Declare the custom rendering function for the 'View' of field 'Color'
customJSLinkRendering.RenderColorField = function (context)
{
  var colorField = context.CurrentItem.Color;

  // Declare a local variable to hold the output color
  var color = '';

  // Evaluate the values of the 'Color' field and render it accordingly
  switch (colorField)
  {
    case 'Red':
      color = 'red';
      break;
    case 'Green':
      color = 'green';
      break;
    case 'Blue':
      color = 'blue';
      break;
    case 'Yellow':
      color = 'yellow';
      break;
    default:
      color = 'white';
      break;
  }

  // Render the output for the 'Color' field
  return "<div style='float: left; width: 20px; height: 20px; margin: 5px; border: 1px solid rgba(0,0,0,.2);background:" + color + "' />";
};

// Invoke the custom rendering function
customJSLinkRendering.CustomizeFieldRendering();

En la siguiente captura de pantalla puede ver cómo se configura la propiedad JSLink en el elemento web de vista de lista.

Configuración de la propiedad JSLink en el elemento web de vista de lista

Si ha cargado el archivo JavaScript en la biblioteca Activos del sitio, el valor de la propiedad JSLink puede ser "~site/SiteAssets/customColorRendering.js".

Puede ver cómo funciona la representación personalizada de la lista.

Representación personalizada del campo

Como puede ver, los campos Color representan un cuadro de color que se rellena con el color seleccionado en el nivel de elemento.

Nota:

Para aprovisionar este tipo de solución en un sitio "clásico", puede usar una plantilla de aprovisionamiento PnP, que puede aprovisionar a la vez la lista con el campo personalizado y la propiedad JSLink.

Para migrar la solución anterior a SharePoint Framework, vea los siguientes pasos.

Crear una solución nueva de SharePoint Framework

  1. Desde la consola, cree una carpeta para el proyecto:

    md spfx-custom-field-extension
    
  2. Vaya a la carpeta del proyecto:

    cd spfx-custom-field-extension
    
  3. En la carpeta del proyecto, ejecute el generador de Yeoman de SharePoint Framework para aplicar scaffolding a un nuevo proyecto de SharePoint Framework:

    yo @microsoft/sharepoint
    
  4. En el momento en que se le solicite, introduzca los siguientes valores (seleccione la opción predeterminada para todas las solicitudes que se omitan a continuación):

    • ¿Cuál es el nombre de la solución?: spfx-custom-field-extension
    • ¿Cuál es el tipo de componente del lado cliente que se va a crear?: Extensión
    • ¿Qué tipo de extensión del lado cliente se va a crear? Personalizador de campo
    • ¿Cuál es el nombre del personalizador de campo? CustomColorField
    • ¿Qué plantilla le gustaría usar?: sin marco de JavaScript
  5. Inicie Visual Studio Code (o el editor de código que prefiera) y empiece a desarrollar la solución. Para iniciar Visual Studio Code, puede ejecutar la siguiente instrucción.

    code .
    

Definir el nuevo personalizador de campo con JavaScript

Para reproducir el mismo comportamiento de la JSLink representación de campos personalizados, debe implementar la misma lógica mediante código del lado cliente dentro de la nueva solución de SharePoint Framework. Para realizar esta tarea, complete los pasos siguientes.

  1. Abra el archivo ./src/extensions/customColorField/CustomColorFieldFieldCustomizer.manifest.json. Copie el valor de la propiedad id y guárdelo en un lugar seguro, ya que lo necesitará más adelante.

  2. Abra el archivo ./src/extensions/customColorField/CustomColorFieldFieldCustomizer.ts y edite el contenido conforme al siguiente fragmento de código:

    import { Log } from '@microsoft/sp-core-library';
    import { override } from '@microsoft/decorators';
    import {
      BaseFieldCustomizer,
      IFieldCustomizerCellEventParameters
    } from '@microsoft/sp-listview-extensibility';
    
    import * as strings from 'CustomColorFieldFieldCustomizerStrings';
    import styles from './CustomColorFieldFieldCustomizer.module.scss';
    
    /**
    * If your field customizer uses the ClientSideComponentProperties JSON input,
    * it will be deserialized into the BaseExtension.properties object.
    * You can define an interface to describe it.
    */
    export interface ICustomColorFieldFieldCustomizerProperties {
      // This is an example; replace with your own property
      sampleText?: string;
    }
    
    const LOG_SOURCE: string = 'CustomColorFieldFieldCustomizer';
    
    export default class CustomColorFieldFieldCustomizer
    extends BaseFieldCustomizer<ICustomColorFieldFieldCustomizerProperties> {
    
      @override
      public onInit(): Promise<void> {
        // Add your custom initialization to this method.  The framework will wait
        // for the returned promise to resolve before firing any BaseFieldCustomizer events.
        Log.info(LOG_SOURCE, 'Activated CustomColorFieldFieldCustomizer with properties:');
        Log.info(LOG_SOURCE, JSON.stringify(this.properties, undefined, 2));
        Log.info(LOG_SOURCE, `The following string should be equal: "CustomColorFieldFieldCustomizer" and "${strings.Title}"`);
        return Promise.resolve();
      }
    
      @override
      public onRenderCell(event: IFieldCustomizerCellEventParameters): void {
    
        var colorField = event.fieldValue;
    
        // Declare a local variable to hold the output color
        var color = '';
    
        // Evaluate the values of the 'Color' field and render it accordingly
        switch (colorField)
        {
          case 'Red':
            color = 'red';
            break;
          case 'Green':
            color = 'green';
            break;
          case 'Blue':
            color = 'blue';
            break;
          case 'Yellow':
            color = 'yellow';
            break;
          default:
            color = 'white';
            break;
        }
    
        // Render the output for the 'Color' field
        event.domElement.innerHTML = "<div style='float: left; width: 20px; height: 20px; margin: 5px; border: 1px solid rgba(0,0,0,.2);background:" + color + "' />";
      }
    
      @override
      public onDisposeCell(event: IFieldCustomizerCellEventParameters): void {
        // This method should be used to free any resources that were allocated during rendering.
        // For example, if your onRenderCell() called ReactDOM.render(), then you should
        // call ReactDOM.unmountComponentAtNode() here.
        super.onDisposeCell(event);
      }
    }
    

    Como puede ver, el contenido del método onRenderCell() es casi el mismo que el método anterior RenderColorField() en la JSLink implementación. Las únicas diferencias son:

    • Para recuperar el valor del campo actual, debe leer la propiedad event.fieldValue del argumento de entrada del método onRenderCell().
    • Para devolver el código HTML personalizado para representar el campo, debe asignar un valor a la propiedad innerHTML del objeto event.domElement, que representa el contenedor HTML de salida de la representación de campo.

    Aparte de estos pequeños cambios, puede reutilizar prácticamente el mismo código JavaScript que antes.

    Puede ver el resultado en la siguiente ilustración.

    Personalizador de campo representado en la lista

Probar la solución en modo de depuración

  1. Volver a la ventana de la consola y ejecutar el siguiente comando para compilar la solución y ejecutar el servidor local Node.js para hospedarlo.

    gulp serve --nobrowser
    
  2. Abra su explorador favorito y vaya a una lista "moderna", que tiene un campo personalizado con el nombre Color y el tipo Elección con las mismas opciones de valor que antes (Rojo, Verde, Azul, Amarillo). Con el tiempo, puede usar la lista que creó en el sitio "clásico", solo tiene que verla con la nueva experiencia "moderna". Ahora, anexe los siguientes parámetros de cadena de consulta a la dirección URL de la página AllItems.aspx .

    ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&fieldCustomizers={"Color":{"id":"c3070978-d85e-4298-8758-70b5b5933076"}}
    

    En esta cadena de consulta, reemplace el GUID por el valor de id que ha guardado en el archivo CustomColorFieldFieldCustomizer.manifest.json y el nombre de propiedad Color hace referencia al nombre del campo que quiere personalizar. Si lo prefiere, también puede especificar un objeto de configuración personalizada, serializado en formato JSON, como parámetro adicional para la construcción del personalizador de campo.

    Tenga en cuenta que al ejecutar la solicitud de página, se le pedirá un cuadro de mensaje de advertencia con el título "Permitir scripts de depuración?", que le pide su consentimiento para ejecutar código desde localhost por motivos de seguridad. Si desea depurar y probar localmente la solución, tiene que permitir que "Cargar scripts de depuración".

    Nota:

    Como alternativa, puede crear entradas de configuración de servidor en el archivo config/serve.json del proyecto para automatizar la creación de los parámetros de cadena de consulta de depuración como se describe en este documento: Depurar soluciones de SharePoint Framework en páginas modernas de SharePoint

Definir el nuevo personalizador de campo con TypeScript

Ya puede reemplazar el código JavaScript por TypeScript para poder aprovechar el enfoque completo de tipo de TypeScript.

  1. Abra el archivo ./src/extensions/customColorField/CustomColorFieldFieldCustomizer.module.scss. Este archivo, que es una Sass CSS, representa el estilo de la interfaz de usuario del personalizador de campo. Reemplace el contenido del archivo SCSS por el siguiente.

    .CustomColorField {
      .cell {
        float: left;
        width: 20px;
        height: 20px;
        margin: 5px;
        border: 1px solid rgba(0,0,0,.2);
      }
    
      .cellRed {
        background: red;
      }
    
      .cellGreen {
        background: green;
      }
    
      .cellBlue {
        background: blue;
      }
    
      .cellYellow {
        background: yellow;
      }
    
      .cellWhite {
        background: white;
      }
    }
    
  2. Reemplace la implementación del método onRenderCell() por el siguiente fragmento de código.

    @override
    public onRenderCell(event: IFieldCustomizerCellEventParameters): void {
      // Read the current field value
      let colorField: String = event.fieldValue;
    
      // Add the main style to the field container element
      event.domElement.classList.add(styles.CustomColorField);
    
      // Get a reference to the output HTML
      let fieldHtml: HTMLDivElement = event.domElement.firstChild as HTMLDivElement;
    
      // Add the standard style
      fieldHtml.classList.add(styles.cell);
    
      // Add the colored style
      switch(colorField)
      {
        case "Red":
          fieldHtml.classList.add(styles.cellRed);
          break;
        case "Green":
          fieldHtml.classList.add(styles.cellGreen);
          break;
        case "Blue":
          fieldHtml.classList.add(styles.cellBlue);
          break;
        case "Yellow":
          fieldHtml.classList.add(styles.cellYellow);
          break;
        default:
          fieldHtml.classList.add(styles.cellWhite);
          break;
      }
    }
    

    Observe que la nueva implementación del método usa un enfoque totalmente tipado y asigna la clase CSS cell al elemento secundario DIV del elemento actual del campo, junto con otra clase CSS personalizada para definir el color de destino de DIV según el valor seleccionado para el campo.

  3. Ejecute de nuevo el personalizador de campo en modo de depuración y vea los resultados.

Empaquetar y hospedar la solución

Si le gusta el resultado, ya puede empaquetar la solución y hospedarla en una infraestructura de hospedaje real. Antes de crear la agrupación y el paquete, deberá declarar un archivo XML de Feature Framework para aprovisionar la extensión.

Revisar los elementos de Feature Framework

  1. En el editor de código, abra el archivo /sharepoint/assets/elements.xml. Puede ver el aspecto que debe tener el archivo en el siguiente fragmento de código.

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
        <Field ID="{40475661-efaf-447a-a220-c992b20ec1c3}"
               Name="SPFxColor"
               DisplayName="Color"
               Title="Color"
               Type="Choice"
               Required="FALSE"
               Group="SPFx Columns"
               ClientSideComponentId="c3070978-d85e-4298-8758-70b5b5933076">
        </Field>
    </Elements>
    

    Como puede ver, recuerda a un archivo del marco de características de SharePoint, pero define un elemento Field personalizado con un campo de tipo Choice, que usa el atributo ClientSideComponentId para hacer referencia a la propiedad id del personalizador de campo y puede que haya un atributo ClientSideComponentProperties para definir las propiedades de configuración personalizadas necesarias en la extensión.

  2. Abra el archivo./config/package-solution.json. En el archivo puede ver que hay una referencia al archivo elements.xml en la sección assets.

    {
      "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
      "solution": {
        "name": "spfx-custom-field-extension-client-side-solution",
        "id": "ab0fbbf8-01ba-4633-8498-46cfd5652619",
        "version": "1.0.0.0",
        "features": [{
          "title": "Application Extension - Deployment of custom action.",
          "description": "Deploys a custom action with ClientSideComponentId association",
          "id": "090dc976-878d-44fe-8f8e-ac603d094aa1",
          "version": "1.0.0.0",
          "assets": {
            "elementManifests": [
              "elements.xml"
            ]
          }
        }]
      },
      "paths": {
        "zippedPackage": "solution/spfx-custom-field-extension.sppkg"
      }
    }
    

Empaquetar e implementar la solución

Después debe empaquetar el paquete de soluciones en el catálogo de aplicaciones. Para realizar esta tarea, siga estos pasos.

Prepare e implemente la solución para el espacio empresarial de SharePoint Online:

  1. Ejecute la tarea siguiente para agrupar la solución. Esto crea una compilación de versión del proyecto:

    gulp bundle --ship
    
  2. Ejecute la siguiente tarea para empaquetar la solución. Este comando crea un paquete *.sppkg en la carpeta sharepoint/solution .

    gulp package-solution --ship
    
  3. En el Catálogo de aplicaciones del espacio empresarial, cargue (o arrastre y coloque) el nuevo paquete de solución del lado cliente y, después, seleccione el botón Implementar.

Instalar y ejecutar la solución

  1. Abra el explorador y navegue a cualquier sitio de destino "moderno".

  2. Vaya a la página Contenidos del sitio y seleccione agregar una nueva Aplicación.

  3. Seleccione esta opción para instalar una nueva aplicación De su organización para examinar las soluciones disponibles en el Catálogo de aplicaciones.

  4. Seleccione la solución denominada spfx-custom-field-extension-client-side-solution e instálela en el sitio de destino.

    Agregar una interfaz de usuario de aplicación para agregar la solución a un sitio

  5. Cuando se haya completado la instalación de la aplicación, cree una lista personalizada, edite la configuración de la lista y agregue una nueva columna de columnas de sitio ya existentes. Seleccione el grupo de columnas denominado Columnas SPFx y agregue el campo Color.

    Agregar el campo a la lista

  6. Edite el campo que ha agregado y configure algunos valores de color (como Rojo, Verde, Azul y Amarillo) y guarde la configuración de campo.

  7. Agregar algunos elementos a la lista y ver el resultado en la vista de lista. Debe tener un aspecto similar de la siguiente captura de pantalla.

    Personalizador de campo en acción

¡Disfrute del nuevo personalizador de campo creado con extensiones de SharePoint Framework!

Vea también