Message and action

Message/action is a way to support communication between widget to widget, widget to framework, and framework to widget. Widget/framework can publish a message, and they can listen to a message as well. A message is identified by MessageType, which is defined by the jimu framework. There are some message types defined in jimu, such as ExtentChange and DataRecordsSelectionChange.

Publishing a message

A widget calls MessageManager.getInstance().publishMessage(message) to publish a message. For example, the List widget publishes the DataRecordsSelectionChange message when a list item is clicked or a Map widget publishes the ExtentChange message when the view is changed, which updates the List widget content. The following MessageTypes are supported:

  • StringSelectionChange
  • ExtentChange
  • DataRecordsSelectionChange
  • DataRecordSetChange

Each message has a class to define it. For example, the ExtentChange message is defined by ExtentChangeMessage class, this class defines the extent property, which is the message payload.

To publish a message, a widget should declare the published messages in the manifest.json file.

Use dark colors for code blocksCopy
1
2
3
  "publishMessages": [
    "DATA_RECORDS_SELECTION_CHANGE"
  ]

Creating a message action

To create a message action, you will need to extend AbstractMessageAction class. There are several methods and functions that help with developing message actions.

The filterMessageDescription method is used to filter the available actions in the builder.

Use dark colors for code blocksCopy
1
2
3
4
5
export default class QueryAction extends AbstractMessageAction{
  filterMessageDescription: (messageDescription: MessageDescription): boolean{
    return [MessageType.StringSelectionChange, MessageType.DataRecordsSelectionChange].indexOf(messageDescription.messageType) > -1;
  }
}

filterMessage method is used to filter messages in message manager.

Use dark colors for code blocksCopy
1
2
3
filterMessage(message: Message): boolean{
    return true;
  }

Some actions may need a setting UI to configure the action behavior. To achieve this, you can declare the settingUri in manifest.json. In some specific cases, you may want to skip the setting UI. To achieve this, you can override the getSettingComponentUri method and return null in the applicable cases.

An action setting UI component is a React component with some injected props. When the user changes the config, you should call this.props.onSettingChange to save the config, which will be available in the onExecute method.

Use dark colors for code blocksCopy
1
2
3
4
this.props.onSettingChange({
  actionId: this.props.actionId,
  config: {} // the action config
})

onExecute method handles the logic for what you would like to happen for your message type. In the snippet below, it basically selects the action based on the message type and sends it from the application to the store using getAppStore() function using the dispatch property. This dispatches the redux action and allows the state to be updated. Learn more about redux actions and using the store in Redux.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
onExecute(message: Message, actionConfig?: any): Promise<boolean> | boolean{
    let q = `${(actionConfig as ConfigForStringChangeMessage).fieldName} = '${message}'`
    switch(message.type){
      case MessageType.StringSelectionChange:
        q = `${(actionConfig as ConfigForStringChangeMessage).fieldName} = '${(message as StringSelectionChangeMessage).str}'`
        break;
      case MessageType.DataRecordsSelectionChange:
         q = `${actionConfig.fieldName} = ` +
          `'${(message as DataRecordsSelectionChangeMessage).records[0].getFieldValue(actionConfig.fieldName)}'`
        break;
    }
    getAppStore().dispatch(appActions.widgetStatePropChange(this.widgetId, 'queryString', q));
    return true;
}

Only plain JSON objects are able to be stored in the Redux store. If you need to pass a complex JavaScript object, you can store it in a mutable store by using the MutableStoreManager. After you update the value, your widget can be re-rendered as well. In the action:

Use dark colors for code blocksCopy
1
MutableStoreManager.getInstance().updateStateValue(this.widgetId, 'theKey', theComplexObject)

In the widget, you can access the object by using:

Use dark colors for code blocksCopy
1
this.props.mutableStateProps.theKey

In the manifest.json there is a messageActions property that provides the location and information for the message action extension.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9

 "messageActions": [
  {
    "name": "query",
    "label": "Query",
    "uri": "actions/query-action",
    "settingUri": "actions/query-action-setting"
  }
]

i18n support

The support for languages in your message action follows the same pattern as a widget with one key difference. A message action has a Select an action panel that allows users to select an action. Therefore you will need to have a file called default.ts in the runtime/translations folder with the property names of your actions. The framework handles the translations of the action label in this panel. As a result, the property of the label needs to have this naming convention _action_<actionName>_label.

Use dark colors for code blocksCopy
1
2
3
4
5

export default {
  _widgetLabel: 'Message subscriber',
  _action_query_label: 'Query'
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.