教程:在组件中定义自定义事件

[本主题是预发行文档,有可能会有所更改。]

在本教程中,你将生成一个代码组件,该组件使用自定义事件,并使用画布和模型驱动应用对其进行测试。 详细了解自定义事件预览。

目标

本教程中的步骤将指导你创建一个带有两个按钮的代码组件,这两个按钮会触发不同的事件,供宿主应用程序响应。 你将定义两个事件: customEvent1 和 customEvent2。 然后,代码组件公开两个导致这些事件发生的按钮。

画布应用

画布应用在这些事件上使用 Power Fx 表达式切换控件的可见和显示模式属性:

此图显示了此示例定义两个自定义事件的目标

模型驱动应用

模型驱动应用使用客户端 JavaScript 在发生相应事件时显示警报。

先决条件

你应该已经知道如何:

创建新控件

  1. 使用以下命令创建新组件:

    pac pcf init -n EventSample -ns SampleNamespace -t field -fw react -npm

  2. 编辑清单以添加新事件

<property name="sampleProperty"
   display-name-key="Property_Display_Key"
   description-key="Property_Desc_Key"
   of-type="SingleLine.Text"
   usage="bound"
   required="true" />
<resources>
   <code path="index.ts"
      order="1"/>
   <platform-library name="React"
      version="16.8.6" />
   <platform-library name="Fluent"
      version="8.29.0" />
   <css path="css/SampleEventPCF.css" order="1" />
   <resx path="strings/SampleEventPCF.1033.resx" version="1.0.0" />
</resources>

定义事件

在 EventSample\HelloWorld.tsx 控件文件中,定义接口中的两个事件,并将事件绑定到两个不同的按钮。 此外,更新导入以包括 DefaultButton ,如以下更改所示。

import * as React from 'react';
import { Label } from '@fluentui/react';

export interface IHelloWorldProps {
  name?: string;
}

export class HelloWorld extends React.Component<IHelloWorldProps> {
  public render(): React.ReactNode {
    return (
      <Label>
        {this.props.name}
      </Label>
    )
  }
}

修改 updateview 方法

在 EventSample\Index.ts中,修改 updateView 方法 以添加两个按钮事件的处理程序。 这些处理程序将清单中定义的两个事件添加到传递给控件的上下文中的事件。

public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
   const props: IHelloWorldProps = { name: 'Hello, World!' };
   return React.createElement(
      HelloWorld, props
   );
}

构建和打包

像往常一样,需要完成以下步骤才能使用此控件:

  1. 创建和生成代码组件
  2. 打包代码组件
  3. 部署代码组件。

在画布应用中使用

若要在画布应用中使用此控件,需要:

  1. 创建新的空白画布应用

  2. 将新组件添加到画布应用

  3. 添加新控件。 此示例使用文本控件。

    已添加控件的 Canvas 应用的图像。

  4. 向应用添加两个全局变量: isVisible 和 canEdit。

  5. 将canEdit设置为文本控件的DisplayMode属性。

    文本控件的 DisplayMode 属性的图像

  6. 将isVisible设置为文本控件的Visible属性。

    文本控件的“可见”属性的图像

  7. 对新的自定义控件设置自定义操作,以在单击按钮时更新 isVisible 和 canEdit 变量。

    新组件的自定义事件属性的图像

    Event Power Fx 表达式
    customEvent1 If(isVisible, Set (isVisible, false), Set (isVisible, true))
    customEvent2 If(canEdit = DisplayMode.Edit, Set(canEdit, DisplayMode.Disabled), Set (canEdit, DisplayMode.Edit))

测试画布应用

  1. 按下触发事件 1。

    预期:文本控件在可见和隐藏之间切换

  2. 按下 触发事件 2。

    预期:文本控件在可编辑和只读状态之间切换。

在模型驱动应用中使用

Note

这些步骤参考 演练:编写第一个客户端脚本中所述的说明。

  1. 创建一个新的 JavaScript Web 资源,以在窗体的 onLoad 事件上运行。 此脚本在表单加载时,将两个事件处理程序绑定到控件的新事件上。

    /* eslint-disable */
    "use strict";
    
    var MyScriptsNameSpace = window.MyScriptsNameSpace || {};
    (function () {
    
    const controlName1 = "cr116_personid";
    
    this.onLoad = function (executionContext) {
       const formContext = executionContext.getFormContext();
    
       const sampleControl1 = formContext.getControl(controlName1);
       sampleControl1.addEventHandler("customEvent1", this.onSampleControl1CustomEvent1);
       sampleControl1.addEventHandler("customEvent2", this.onSampleControl1CustomEvent2);
    };
    
    this.onSampleControl1CustomEvent1 = function (params) {
       alert(`SampleControl1 Custom Event 1`);
    }.bind(this);
    
    this.onSampleControl1CustomEvent2 = function (params) {
       alert(`SampleControl1 Custom Event 2`);
    }.bind(this);
    
    }).call(MyScriptsNameSpace);
    
  2. 像平时一样完成以下步骤:

    1. 将新的 JavaScript 文件作为 Web 资源上传。
    2. 将组件添加到模型驱动表单。
    3. 将 Webresource 关联到表单。
  3. 配置 On Load 事件 ,如下图所示:

    模型驱动应用表单的 JavaScript 绑定图像

  4. 测试应用。

    当你转到该表单并按下 触发事件 1 时,会显示SampleControl1 Custom Event 1警报。 按 Trigger 事件 2 时,将显示 SampleControl1 Custom Event 2警报。

在事件中传递有效载荷

如 为模型驱动应用定义事件中所述,可以在模型驱动应用中的事件中传递有效负载。 可以通过以下方式修改此示例,以查看其工作原理。

图示显示多个控件生成多个事件,并进行回调

通过事件传递有效载荷

修改 EventSample\index.ts,使事件传递消息有效载荷,并在第二个事件中还传递一个回调函数来更改内部变量

public updateView(context: ComponentFramework.Context<IInputs>): React.ReactElement {
   const props: IHelloWorldProps = {
      onCustomEvent1: ()=> {
            context.events.customEvent1()
      },
      onCustomEvent2: () => {
            context.events.customEvent2()
      }
   };
   return React.createElement(
      HelloWorld, props
   );
}

Then:

  1. 重新生成并部署组件。

  2. 将另一个字段添加到 之前 使用的窗体,并设置该字段以使用新组件。

    图示显示已添加到窗体中的多个控件

在事件处理程序中使用有效载荷

onLoad更新函数以设置自定义控件上的事件处理程序以响应来自这两个控件的事件,并利用正在传递的参数

/* eslint-disable */
"use strict";

var MyScriptsNameSpace = window.MyScriptsNameSpace || {};
(function () {

const controlName1 = "cr116_personid";

this.onLoad = function (executionContext) {
   const formContext = executionContext.getFormContext();

   const sampleControl1 = formContext.getControl(controlName1);
   sampleControl1.addEventHandler("customEvent1", this.onSampleControl1CustomEvent1);
   sampleControl1.addEventHandler("customEvent2", this.onSampleControl1CustomEvent2);
};

this.onSampleControl1CustomEvent1 = function (params) {
   alert(`SampleControl1 Custom Event 1`);
}.bind(this);

this.onSampleControl1CustomEvent2 = function (params) {
   alert(`SampleControl1 Custom Event 2`);
}.bind(this);

}).call(MyScriptsNameSpace);

测试模型驱动应用

  1. 导航到该表单。

  2. 在第一个字段上按下触发事件 1。

    预期:在第一个字段上显示弹出窗口 SampleControl1 自定义事件 1:来自事件 1 的问候。

  3. 在第一个字段上按下触发事件 2。

    预期:在第一个字段上显示弹出窗口 SampleControl1 自定义事件 2:来自事件 2 的问候,随后第一个控件弹出提示,内容为 事件 2 默认未被阻止

  4. 在第二个字段上按触发事件 1。

    预期:在第二个字段上显示弹出窗口 SampleControl2 自定义事件 1:来自事件 1 的问候。

  5. 在第二个字段上按下触发事件 2。

    预期:在第二个字段上显示弹出窗口 SampleControl2 自定义事件 2:来自事件 2 的问候,随后第二个控件弹出提示,内容为 事件 2 默认行为被阻止

定义事件(预览版)