3

I want to pass data between two controllers (in addition to routing parameters) and I would like to know the correct way to do this.

For example: when I navigate to pattern /order/{id}, I do this in the view controller:

this.getRouter().navTo("order", {
  id: sOrderId
});

I want to pass additional JSON object which I don't want to be part of routing parameter.

What should I do in this case?

--edit
Wanted to add what I like to achieve with this

I want pass data from master to detail. Both master and detail page has individual routing patterns assigned. So user can land on master or detail directly. When they land on master - user can choose bunch of detail items, and navigate to first detail item, and from there navigate to other items he/she selected earlier on master. So what I want to pass is this selection from master controller to detail controller.

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Austin
  • 31
  • 1
  • 3
  • 1
    [This](https://experience.sap.com/fiori-design-web/wp-content/uploads/sites/5/2016/02/03_local_edit_mode_b.png) is kind of what I am trying to do. We select multiple items in the table in the first view - click edit (in the first view) - we go to edit of detail page - and click save and next to navigate through the rest of items selected. does it makes sense ?. I am still using split app but it is more like master has orders - detail has order details + some items, select items to go into item details. so 3 levels. And back-end is oData and each view is bound to correct entity. – Austin Feb 19 '18 at 19:10
  • I could make my own prototype to let you take a look when time allows but generally, storing each selected entry keys in a client-side model and then binding element via those keys (--> paths) is the way to go I guess.. That's the "cleanest" way I could think of right now. – Boghyon Hoffmann Feb 19 '18 at 23:52
  • Ok, going with client side JSON model. – Austin Feb 20 '18 at 23:17

3 Answers3

5

Note: If the intention is to pass selected keys from the main view to the detail view, see https://stackoverflow.com/a/48870579/5846045 instead.


Using a client-side model

Usually, data are stored separately in models instead of assigned to local variables and passing them around. Model data can be then shared with anything that can access the model (e.g. View for data binding). Here is an example with a client-side model (JSONModel):

  1. Create a JSONModel which is set on a parent ManagedObject. E.g. on the Component via manifest.json:

    "sap.ui5": {
      "models": {
        "myModel": {
          "type": "sap.ui.model.json.JSONModel"
        }
      }
    }
    
  2. In the controller A, set the object to pass before navigating:

    const dataToPass = /*...*/
    this.getOwnerComponent().getModel("myModel").setProperty("/data", dataToPass, null, true);
    
  3. In the controller B, do something with the passed data. E.g. on patternMatched handler:

    onInit: function() {
      const orderRoute = this.getOwnerComponent().getRouter().getRoute("order");
      orderRoute.attachPatternMatched(this.onPatternMatched, this);
    },
    
    onPatternMatched: function() {
      /*Do something with:*/this.getOwnerComponent().getModel("myModel").getProperty("/data");
    },
    

Using NavContainer(Child) events

There are several navigation-related events such as navigate, BeforeHide, BeforeShow, etc. which contain both views - the source view (from) and the target view (to).

You can make use of the API data to pass the data. Here is an example:

  1. In the controller A:

    onInit: function() {
      this.getView().addEventDelegate({
        onBeforeHide: function(event) {
          const targetView = event.to;
          const dataToPass = /*...*/
          targetView.data("data", dataToPass);
        }
      }, this);
    },
    
  2. In the controller B:

    onInit: function() {
      this.getView().addEventDelegate({
        onBeforeShow: function(event) {
          /*Do something with:*/this.getView().data("data");
        }
      }, this);
    },
    

See also the related documentation topic: Passing Data when Navigating

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
0

You can create a local model (usually a JSONModel) and set it to inside your app Component.

// inside Component.js
var model = new sap.ui.model.json.JSONModel({ foo: “bar”});
this.setModel(model);

Inside each controller you can use

var model = this.getOwnerComponent().getModel();
console.log(model.getProperty(“/foo”));
fabiopagoti
  • 1,467
  • 14
  • 31
0

You can do this using the SAPUI5 event bus. The data can be shared via publish/subscribe.

i000174
  • 1,107
  • 10
  • 15