0

I have a Controller. In which I am defining data and setting it to a model. Later I want to bind this model's data to a List control in a view. Problem: But the problem is the data doesn't show up in the respective control to whom I am binding it. Can anyone help what I am doing wrong?

Here is my code for the controller and my view:

App.view.xml

<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core"
displayBlock="true" controllerName="opensap.examples.controller.App" height="100%">
<Page title="List Page">
    <content>
        <List headerText="{/question}" id="myList" items="{ path: '/answers' }">
            <items>
                <InputListItem label="{answerText}">
                    <CheckBox></CheckBox>
                </InputListItem>
         </List>
        <Button press="load" text="Click Me"></Button>
    </content>
</Page></mvc:View>

App.controller.js

sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"], function(Controller, JSONModel) {

var oData = {
    "question": "Which pet do you like from the following?",
    "answers": [{
        "answerText": "Cats"
    }, {
        "answerText": "Rabbits"
    }, {
        "answerText": "Dogs"
    }, {
        "answerText": "Hamsters"
    }]
};

var oModel;


Controller.extend("opensap.examples.controller.App", {

    onInit: function() {
         oModel = new JSONModel();
         oModel.setData(oData);
         console.log(oModel);
    }, load: function() {
        console.log(oModel);
    }
}); });
loki
  • 648
  • 18
  • 37

1 Answers1

1

The fact, that we need multiply models, we are assigning names to our models. You'll benefit of more consistency and better readability and you have full control of your application. If you bind your model this way, you must use element binding (see: https://sapui5.netweaver.ondemand.com/1.34.7/docs/guide/91f05e8b6f4d1014b6dd926db0e91070.html).

One more thing: you forget the ',' to seperate onInit from load ;) I fixed that for you for the following code.

And the last thing :D If you declare a variable in a function, you can not access in another function, due to the change of the scope (see: What is the scope of variables in JavaScript?) You need to access your model in a global scope! Either you bind your model to this or you access your model by the reference-name

loki now wants to display the answers dynamically (see comments below this post). To achieve this, you need the usage of Aggregation Binding (see: https://sapui5.hana.ondemand.com/#docs/guide/91f057786f4d1014b6dd926db0e91070.html). Aggregation Binding lets you "loop" through your JS-Object (JSON). You might see the difference at the <List>-Element :)

App.view.xml

<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" xmlns:l="sap.ui.layout" xmlns:f="sap.ui.layout.form" xmlns:core="sap.ui.core"
displayBlock="true" controllerName="opensap.examples.controller.App" height="100%">
<Page title="List Page">
    <content>
        <List headerText="{myModel>/question}" items="{myModel>/answers}">
            <items >
                <InputListItem label="{myModel>answerText}"> <!-- Aggregation Binding -->
                    <CheckBox></CheckBox>
                </InputListItem>
         </List>
        <Button press="load" text="Click Me"></Button>
    </content>
</Page>
</mvc:View>

App.controller.js

sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/model/json/JSONModel"], function(Controller, JSONModel) {

var oData = {
    "question": "Which pet do you like from the following?",
    "answers": [
          {"answerText": "Cats"}, 
          {"answerText": "Rabbits"},
          {"answerText": "Dogs"},
          {"answerText": "Hamsters"}
     ]
 };

// edit
var oModel; // <-- might work, but it is not a good practice @sapui5 :)


Controller.extend("opensap.examples.controller.App", {

    onInit: function() {
         oModel = new sap.ui.model.json.JSONModel();
         this.setModel(oModel, "myModel");
         oModel.setData(oData);
         console.log(oModel);
    },

    load: function() {
         // if you bind your model to the window-context (this)
         //console.log(this.oModel.getData());
         var myModel = this.getView().getModel("myModel");
         console.log(myModel.getData());
         // I always use ^-this-^ approach.
    }
}); });
Community
  • 1
  • 1
Sauerbrei
  • 443
  • 4
  • 14
  • Hi corax, the ', ' I forgot while pasting the code here on stackoverflow i have it in my code orelse it gives compilation error. Thank you for the edit. So you are saying I should name my model and try? Also thank you for the link which you suggested I am finding it useful. – loki May 17 '17 at 10:28
  • yes, try it out please. This code is not tested yet, but will be edited if there are any errors. Please make sure, to backup your current code (!!!!) :) – Sauerbrei May 17 '17 at 10:31
  • I want to keep the answers as a collection which consist of answerText as a key with different values as I defined before. The should be dynamic according to number of answerText present in answers collection it should display that many InputListItems For eg: For 1 item in answers collection only 1 inputlistitem will be displayed if there are 2 then 2 inputlistitem and so on. – loki May 17 '17 at 10:37
  • 1
    please open another question for this ;) you need a different approach for this. (Aggregation Binding, see: https://sapui5.hana.ondemand.com/#docs/guide/91f057786f4d1014b6dd926db0e91070.html). – Sauerbrei May 17 '17 at 10:41
  • oh yes that is what I am trying to achieve aggregation binding. Thank you for the link. What should i specify in new question which I should open ? s – loki May 17 '17 at 10:46