Soraky
Soraky

Reputation: 149

How to properly use JSONModel and setModel?

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?

Upvotes: 5

Views: 12241

Answers (3)

DubZ
DubZ

Reputation: 582

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>

Upvotes: 4

Bernard
Bernard

Reputation: 1238

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.

Upvotes: 4

fareslt
fareslt

Reputation: 198

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

Upvotes: 6

Related Questions