4

I'm trying to create an example screen using SAP Web IDE where clicking different buttons changes different texts around the screen. I have a few functions at the App.controller.js and the code is this (All the functions do the same for now but affect different text areas):

onPressButton2: function () {
  var oData = {
    text: {
      line1: "line1",
      line2: "line2",
      line3: "line3",
      line4: "line4"
    }
  };
  var oModel = new JSONModel(oData);
  this.getView().setModel(oModel);
},

And this is corresponding part at the XML:

<items>
  <Text xmlns="sap.m" text="{/text/line1}" id="text1"/>
  <Text xmlns="sap.m" text="{/text/line2}" id="text2"/>
  <Text xmlns="sap.m" text="{/text/line3}" id="text3"/>
  <Text xmlns="sap.m" text="{/text/line4}" id="text4"/>
</items>

This works, but when I try and change different areas of the screen, the previous changes I made by clicking the buttons disappear. I assume this is because I use setModel anew every time which overwrites it but I cannot find the proper usage.

Should I create a different js file for every section in the screen?
Is there a way to update the model instead of overwriting it all?

Boghyon Hoffmann
  • 17,103
  • 12
  • 72
  • 170
Soraky
  • 119
  • 3
  • 10

3 Answers3

6

Try to declare your JSONModel outside of the onPressButton function. You can declare it in the manifest to be visible for the entire application (controllers and views):

"sap.ui5": {
    "_version": "1.1.0",
    ...
    "models": {
        "i18n": {
            "type": "sap.ui.model.resource.ResourceModel",
            "uri": "i18n/i18n.properties"
        },
        "MyModel" : {
            "type" : "sap.ui.model.json.JSONModel"
        }

Once the model is available you can set the data to it outside of the onPressButton2 function:

this.getOwnerComponent().getModel("MyModel").setData(oData)

Now, in the onPressButton2 function, you can just update the model's data using the setProperty method:

this.getOwnerComponent().getModel("MyModel").setProperty("/text/line1", "NewValue");
TiiJ7
  • 3,332
  • 5
  • 25
  • 37
fareslt
  • 191
  • 1
  • 6
  • Thank you for your input, I understand the idea behind it but can't manage to get it to work even after some tinkering. My problem is, I think, I can't access "MyModel" even after declaring it in the manifest. Not through "this.getOwnerComponent().getModel("MyModel").setData(oData)" or "this.getOwnerComponent().getModel("MyModel").setProperty("/text/line1", "NewValue");" – Soraky Mar 10 '19 at 13:19
  • Are you trying to access the model on onInit() of the controller ? If you are, that is not going to work. Declare your model on the manifest as the previous answer already mentioned and access it on the RouteMatched event of the controller by this.getView().getModel(modelName) – Geraldo Megale Mar 10 '19 at 19:36
  • if you want to use the model just for this very view i suggest not declaring it in the manifest, doing that implies the model is relevant for the whole application. See DubZ answer to see how to create named models. – Erch Mar 11 '19 at 06:37
  • I did declare it in the manifest at first but still couldn't access it. I'm trying to understand why I couldn't right now. As for DubZ answer's, it works great and was exactly what I've been looking for. – Soraky Mar 11 '19 at 09:21
4

I think what you are searching are named models. with named models you are able create different models without overwriting them, if you want to additionally add a new model.

var oModel = new JSONModel(oData);
this.getView().setModel(oModel, "model1");

have a look at the second parameter in the setmodel method. now you can access them in the view with

<items>
  <Text xmlns="sap.m" text="{model1>/text/line1}" id="text1"/>
  <Text xmlns="sap.m" text="{model1>/text/line2}" id="text2"/>
  <Text xmlns="sap.m" text="{model1>/text/line3}" id="text3"/>
  <Text xmlns="sap.m" text="{model1>/text/line4}" id="text4"/>
</items>
DubZ
  • 580
  • 3
  • 12
3

You should create your model during the intilisation phase of the page lifecycle. So, in your instance, create the model and the intial values in the onInit function of the relevant view/page:

onInit: function () {
  var oData = {
    text: {
      line1: "line1",
      line2: "line2",
      line3: "line3",
      line4: "line4"
    }
  };
  var oModel = new JSONModel(oData);
  this.getView().setModel(oModel);

Then, when you need to assign different values to that model for the existing values you would simply set the relevant property in the model as follows:

this.getView().getModel().setProperty("/text/line1", "<new value>");

if you wish to add an additional line you could simply get the existing model values and add the new value:

var mydata =  this.getView().getModel().getProperty("/");
mydata.text["line5"] = "line5";
this.getView().setProperty("/", mydata);

Hope that helps. I trust you are aware of the differences between the un-named model you were using and the concept of a named model.

Bernard
  • 1,208
  • 8
  • 15