cancel
Showing results for 
Search instead for 
Did you mean: 

Data binding not working for Component based SAPUI5 app

Former Member
0 Kudos

I may be going about this wrong but in trying to following documentation on creating SAPUI5 apps that can be added to the Fiori Launchpad, I found the UI Developer Guide that states to Run Your Own Applications in the Sandbox (delivered with SAPUI5 SDK 1.16) you should do the following:

The Fiori sandbox runs your local Fiori apps inside the Fiori launchpad. You have to create a root component for the application. The demo apps serve as reference (see for instance /test-resources/sap/ushell/ demoapp/FioriSandboxDefaultApp/Component.js). 


I've done exactly that(along with the .json configuration) and I can see my app in the Local Sandbox list on the FioriLauchpad.html file when running on my Tomcat v7.0 server. Now the problem is, data binding within the application does not seem to work. I have a mock JSON that I bind the model to in a Main.view.js file using:


var oModel = new sap.ui.model.json.JSONModel();

  oModel.setData({

      "firstName": "Peter",

      "lastName": "Pan"

  });

  sap.ui.getCore().setModel(oModel, "fake");

  var oPage = new sap.m.Page("page", {

  title: "{fake>/firstName}"

  });

However the title of the Page is blank.

While in Chrome, in the Console I can see that the data is there

sap.ui.getCore().getModel("fake").getData() returns the model I set. I'm out of ideas. I will say that a typical MVC app (using a Applicaiton.js file and index.html) worked just fine. Somehow this Component based app broke it.

Is this really needed for a custom SAPUI5 app to run in the Fiori Launchpad??? Can't you just create a Tile in the Catalog and point the URL to a MVC based SAPUI5???

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

As I mentioned, this is a SAPUI5 Component so the index.html page is never executed. From the Local Sandbox Fiori Launchpad (located in the sap/ushell/shells/sandbox/FioriLaunchpad.html). The UI Developer Guide mentions that a Component.js file should be created to be used for the Launchpad. I can see my app listed in the launchpad and it launches, however data binding does not work.

Here is my Component.js file on Gists

Component.js

This kicks off the app (App.controller.js) controller (which has no custom code in the onInit function). The view for this controller (App.view.js) contains the application constructor and fires the Main.view.js snippet in my first post.

App.view.js


createContent : function(oController) {

       this.setDisplayBlock(true);

       this.app = new sap.m.App("core", {

            pages : [ sap.ui.jsview("Main", "Mercury.view.Main") ]

     });

      return this.app;

}

former_member195440
Participant
0 Kudos

Hi Raymond,

I was experiencing the same issue with a UIComponent last week. When you define the root control, it does not seem to take the models from the core like the definition of a view outside of a UIComponent.

I haven't got to the bottom of why this happens but there is a work-around - you can manually set the model on the root control. Be aware that the Component API is marked as "under construction" so this behavior may change in the future.

Have a look at these JSBin examples to see the differences:

Standard Example:

http://jsbin.com/APENUdOL/3/edit

Component Example:

http://jsbin.com/efUNipUr/1/edit

Hope this helps.

Oli

Former Member
0 Kudos

Hi Oli,

Thanks. Glad to know I'm not the only soul out there that has experienced this. I thought it was weird but I didn't realize that it was "under construction" especially since this paradigm is included in the UI Developer Guide on help.sap.com. At any rate, looking at your 2 examples, the first works fine. However the 2nd does not show "Peter" as the title.

Is that was you were trying to show...that it in fact, doesn't work? Or was that supposed to be the work-around?

former_member195440
Participant
0 Kudos

Hi,

If you look at the code in the 2nd link it has commented out code that will make "Peter" appear.


oPage.setModel(oModel, "fake");

You can edit in the JSBin and it will appear on the right, alternatively here is a new link with the modification: JS Bin - Collaborative JavaScript Debugging</title> <link rel="icon" href="h...

Regards,

Oli

Former Member
0 Kudos

Sorry totally missed that!

Former Member
0 Kudos

So for reference here is what I came up with that finally works.

Component.js - for global models

createContent: function(){

  var oMainView = sap.ui.view({

  type: sap.ui.core.mvc.ViewType.JS,

  viewName: "view.App"

  });

  //this is where the magic happens

  oMainView.setModel(sap.ui.getCore().getModel("device"), "device");

  return oMainView;

  },

init: function(){

    

     var deviceModel = new sap.ui.model.json.JSONModel({

        isTouch: sap.ui.Device.support.touch,

        isNoTouch: !sap.ui.Device.support.touch,

        isPhone: jQuery.device.is.phone,

        isNoPhone: !jQuery.device.is.phone,

        listMode: (jQuery.device.is.phone) ? "None" : "SingleSelectMaster",

        listItemType: (jQuery.device.is.phone) ? "Active" : "Inactive"

     });

       

     deviceModel.setDefaultBindingMode("OneWay");

     sap.ui.getCore().setModel(deviceModel,"device");

}

Main.controller.js - models that pertain to the view specifically

onInit: function() {

  var mock = new sap.ui.model.json.JSONModel();

  var $this = this;

  var oPage = $this.getView();

  oPage.setBusy(true);

  jQuery.ajax("model/data.json", {

  dataType: "json",

              success: function(data){

                   $this._dataLoaded(data);

              }

  });

  sap.ui.getCore().setModel(mock, "mock");

  },

_dataLoaded: function(data) {

       sap.ui.getCore().getModel("mock").setData(data);

       var oPage = this.getView();

       //this is where the magic happens

       oPage.setModel(sap.ui.getCore().getModel("mock"), "mock");

       oPage.setBusy(false);

       

}

Thanks Oli for the hint on setting the model on the Page. Now data shows up and is bound to controls.

Former Member
0 Kudos

Hi Raymond and Olive,

Thanks to your inputs on this. I used your concepts to resolve the same issue in a similar premise.

We had to make an existing application to include Component.js. We faced the same issue.

Here I describe both the process to move to Component.js as well a solution to a similar problem.

This application built from the initial setup from Eclipse had defined a global model that can be accessed by all controls from all UI areas by using the setModel method on the SAPUI5 core object. The initial view returned a shell->app(added to shell)->pages(added to app)

For quick reference,the solution is right at the end // ADDED FOR Component.js

Problem:

The following type of code implementation was not picking the values after including Component.js

var oControl = new sap.ui.commons.Button( {

    id : "myButton",

    text : "{View1>MY_BUTTON_TEXT}"

});

Earlier, in index.html, App -> View(initial)

  <script>

  var oApp = new sap.m.App({initialPage:"InitViewId"});

  var oInitPage = sap.ui.view({

  id:"InitViewId",

  type:sap.ui.core.mvc.ViewType.JS

  });

  oApp.addPage(oInitPage);

  oApp.placeAt("content");

  </script>

Moving to Component.js:

Now, in index.html, Shell -> ComponentContainer -> View (initial)

  <script>

  new sap.m.Shell("Shell", {

  title : "AppTitle",

  app : new sap.ui.core.ComponentContainer({

  name : 'x'

  })

  }).placeAt('content');

  </script>

Now, in Component.js

jQuery.sap.declare("x.Component");

sap.ui.core.UIComponent.extend("x.Component", {

  createContent : function() {

  var view = sap.ui.view({

  id:"InitViewId",

  viewName: "x.InitView", // initViewPage.js

  type:sap.ui.core.mvc.ViewType.JS

  });

  return view;

  }

});

Now the initial view returns an app->pages(added to app)

In the main custom AppController where all the models were created and given names associating them to other application module views, I added

  var oResourceModel = new sap.ui.model.resource.ResourceModel({

  bundleUrl : "resource/View1.properties"

  });

  sap.ui.getCore().setModel(oResourceModel,

  "View1Properties");

  // ADDED FOR Component.js

  sap.ui.getCore().byId("GlobalViewId").setModel(oResourceModel,

  "View1Properties");

Thanks,

Ranjesh

SAPUI5 Practitioner

Answers (3)

Answers (3)

Former Member
0 Kudos

Just opening this back up because I still don't see a viable way to do this. The problem I'm having is how to bind "contextual" data to a Page in Component based development.

Consider the following example. A SplitApp. The Master page has a List. You click on an item and want the details of the item presented in the Detail page. How do you bind the context of the selected item to the model of the Detail page??

How does SAP do this in Fiori applications??

qmacro
Developer Advocate
Developer Advocate
0 Kudos

Surendra's implication is correct - the code snippet that you have shown us is enough to get the title in the page. You may want to actually show us more code so that guesswork is less likely. See for more info.

cheers

dj

surendra_pamidi
Contributor
0 Kudos

Hi Raymond,

With the following code I am getting page Header..

<!DOCTYPE html>

<html><head>

    <meta http-equiv='X-UA-Compatible' content='IE=edge' />

    <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

   

    <title>OData Date Formats</title>

      <script src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js' ,

  id="sap-ui-bootstrap" ,

  data-sap-ui-libs="sap.m",

                data-sap-ui-theme="sap_bluecrystal">

  

  </script>

  </head>

  <body>

  <div id='content'></div>

       

           <script>

   var oModel = new sap.ui.model.json.JSONModel();

  oModel.setData({

      "firstName": "Peter",

      "lastName": "Pan"

  });

  sap.ui.getCore().setModel(oModel, "fake");

  var oPage = new sap.m.Page("page", {

  title: "{fake>/firstName}"

  });

  oPage.placeAt("content");

</script>

  

  </body>

</html>

I think you made mistake at some  another place... check it once again totally..

Regards,

Surendra.