2
votes

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.

2
This 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
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
Ok, going with client side JSON model. - Austin

2 Answers

3
votes

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 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 JSONModel:

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

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

    const dataToPass = /*...*/
    this.getOwnerComponent().getModel("myModel").setProperty("/data", dataToPass);
    
  3. In 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 sth 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 controller A

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

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

Related documentation topic: Passing Data when Navigating

0
votes

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”));