Tommy Dorsey
Tommy Dorsey

Reputation: 75

Event Registration in UI5 - attaching multiple listeners to an event

How can I add multiple event listeners to an event in UI5?

We have a master list with a dropdown that is correctly firing a select event on its controller. Sub controllers also need to be informed that this dropdown has changed in order to reload model data.

onAllRolesChange: function(oEvent) {
  var key = oEvent.getParameter("selectedItem").getProperty("text");
  if (this.ScreenId != null) {
    this.loadScreenByRole(key);
    // I could invoke the controllers directly, but that seems wrong
    // controller2.update();
    // controller3.update();
  }
},

I assume what I should be aiming for is to call some sort of registerForEvent() method in each of the controllers, but I don't see anything like that in the SDK. fireEvent() and attachEvent() exist, but the examples I've seen appear to be for creating custom controls, or responding to browser events that SAP hasn't implemented.

Upvotes: 3

Views: 2676

Answers (2)

Boghyon Hoffmann
Boghyon Hoffmann

Reputation: 18054

As of UI5 1.65, multiple event handlers can be assigned when creating ManagedObjects / Controls:

(...) ManagedObjects now accept an array of multiple event listeners for an event. To distinguish this use case from the already supported array with [data, listener, this], an array with multiple listeners must use nested array notation for each listener as well [in JS]. In XMLViews, multiple listeners have to be separated by a semicolon. (source)

Syntax

In XMLView

<Button press=".myControllerMethod; .mySubController.thatMethod" />

In JS

new Button({
  press: [
    [ listener1 ], // 1st listener
    [ data, listener2, thisArg2 ] // 2nd listener
  ]
});

Demo

sap.ui.getCore().attachInit(() => sap.ui.require([
  "sap/ui/core/mvc/XMLView"
], XMLView => XMLView.create({
  definition: `<mvc:View xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m"
    height="100%"
    displayBlock="true"
  >
    <Button text="Press" class="sapUiTinyMargin"
      press="alert('1st event handler'); alert('2nd event handler')"
    />
  </mvc:View>`,
}).then(view => view.placeAt("content"))));
<script id="sap-ui-bootstrap"
  src="https://openui5nightly.hana.ondemand.com/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.ui.core, sap.m"
  data-sap-ui-async="true"
  data-sap-ui-compatVersion="edge"
  data-sap-ui-theme="sap_fiori_3"
></script>
<body id="content" class="sapUiBody"></body>

Upvotes: 2

Nabi
Nabi

Reputation: 2566

You could use the EventBus to inform about the change, and who ever wants could listen for the change. However, if the other controllers are not yet loaded they won't get the events of course... Maybe you can combine this with promises...

You could also use a global model with 2 way binding and use it for your dropdown. When ever the dropdown changes the change is reflected in the corresponding model. At the same time, in your sub controllers you could create a sap.ui.model.Binding(...) for the same global model + path etc used for your dropdown. Additionally, you would attach a handler for the change event of the Binding... That should work as well. However, this has the same disadvantage like using the EventBus, but maybe thatÄs not an issue for you...

Upvotes: 1

Related Questions