SAP UI5 Cross Application Navigation without FLP - sapui5

I have two apps. The first app has a view. There I push a button and then it should change to the second application. I don't want to navigate to the first view, but to the second with a parameter.
I use this:
oCrossAppNavigator.toExternal({
target : {
semanticObject : "Z_APP2",
action : "onPress"
},
params : {
param1 : param1
}
In APP2 I write this in the Component.js:
var oRouter = this.getRouter().initialize();
var oComponentData = this.getComponentData();
if (oComponentData.startupParameters) {
oRouter.navTo("Detail", {
param1 : oComponentData.startupParameters.param1[0],
}, false);
It doesn't switch to the other app. Which action should I write here ?
Do I have to implement something else in App2?

The answer is:
window.location.replace("-- url with parameters here --")
The right system is : window.location.host

I have a same issue.
SAPUI5 provide sap.m.URLHelper which contains redirect method :
sap.m.URLHelper.redirect(sURL, bNewWindow?)
I think SAPUI5 do the same thing than window.location.replace() but more SAPUI5-friendly.

Related

UI5 navContiner bindAggregation not loading the pages

i need to build the page by binding aggregation as below
view
<NavContainer
id="navCon"
class="navContainerControl sapUiSmallMarginBottom" height="50%">
</NavContainer>
controller
onInit : function()
{
var navCon = this.getView().byId("navCon");
navCon.bindAggregation('pages',{
path:'/pages',
factory : jQuery.proxy(this.createPages,this)
});
}
createPages : function(sid,context)
{
var eachpageData = context.getObject();
var grid = new sap.ui.layout.Grid({
defaultSpan:"L4 M6 S6"
});
var page = new sap.m.Page({
id : eachpageData.name,
title : eachpageData.name,
content : grid
});
grid.bindAggregation('content',{path:'data',factory :this.createPageContent});
return page;
},
But when i see from the debugger it has only one page
But when i call navto
handleNav : function(evt)
{
var navCon = this.getView().byId("navCon");
var target = evt.getSource().getText();
if (target) {
//var animation = this.getView().byId("animationSelect").getSelectedKey();
navCon.to(this.getView().byId(target));
} else {
navCon.back();
}
}
and if i see the navCon.getPages() will give 2 pages.
What mistake i have done here?
You are trying to pass the DOM element to the NavContainers.to(DOM) method. This is where its gone wrong.
But NavContainers.to() method can accept id(String) as parameter.
Change your handleNav method as follows it will work.
handleNav : function(evt)
{
var navCon = this.getView().byId("navCon");
var target = evt.getSource().getText();
if (target) {
navCon.to(target);
} else {
navCon.back();
}
}
NavContainers can display only one page. You can add more pages to the pages aggregation, but they will be visible only if a navigation event is fired with the proper parameters. After that, the layout of the new page is loaded and added to the DOM.
In case of SplitApp, application can display two pages (master and detail) if you see it on tablet or desktop; however it's implemented by the use of two NavContainers.
That's why the control inspector returns with one page before the navigation, second page is not part of the DOM until you navigates to it.
If you place a breakpoint into your code instead of using the control inspector, you can call the navCon.getPages() which should return with the number of pages in the aggregation.

How to add a press / tab listener in SAPUI5 on HANA heeding the MVC concept?

The SAPUI5 Developer Guide for SAP HANA (SPS 10) explains in "1.2.2.3.2 Add a Control to Your View" how to add a Listener to a Button (JS View):
var aControls = [];
var oButton = new sap.ui.commons.Button({
id : this.createId("MyButton"),
text : "Hello JS View"
});
aControls.push(oButton.attachPress(oController.doIt));
return aControls;
And how to implement the controller:
doIt : function(oEvent) { alert(oEvent.getSource().getId() + " does it!"); }
Unfortunately the code is not working in our system (SAP HANA SPS 09)
Which is the correct Code using MVC (not model, view, controll in one file)?
Where can I get correct developer information?
You can also directly add the eventhandler in the button declaration:
new sap.m.Button("button12345", {
text : "call function"
press : oController.myTestFunction
});
I figured out how to add a Listener to a button heeding the MVC concept:
View:
createContent : function(oController) {
var btn = new sap.m.Button("button12345", { text : "call function" });
btn.attachPress(null, oController.myTestFunction, null);
return new sap.m.Page({
title : "Title",
content : [btn]
});
}
Controller:
myTestFunction : function() { alert("Successfully called the test function");}

How to Implement Master Detail in Ionic Framework?

I am trying to use Ionic Framework to build a simple Master Detail List application. I can capture the tap event on the list item but how can I load the details view after that.
.controller('TasksController',function($scope){
$scope.tasks = [
{ title : "Collect Coins" },
{ title : "Eat Mushroom" },
{ title : "Find the princess" }
];
$scope.showTaskDetails = function() {
alert('show Task details');
}
});
In the showTaskDetails event. How can I load a different view like Details.html?
The Master Detail pattern is a very easy pattern to implement in Ionic, but you're going about it wrong. You want to set up the details as a separate view and route in your application.
I suggest reading my article on the topic.
http://mcgivery.com/ionic-master-detail-pattern/

SAP UI5 issue, render Calling two time in Custom Control

In view
var oData = {
"SavedSearch" : [
{ name : "Save1" },
{ name : "Save2" },
{ name : "Save3" },
{ name : "Save4" },
{ name : "Save5" }
]
}
var oModel = new sap.ui.model.json.JSONModel();
oModel.setData(oData);
sap.ui.getCore().setModel(oModel,"ModelData");
var oTest = new test({
manageSavedSearch :{
path : "ModelData>/SavedSearch",
template: new sap.ui.commons.Button({
text : "{ModelData>name}"
})
},
});
oTest.placeAt(this);
In Custom Control
sap.ui.core.Control.extend("test",{
metadata:{
properties : {},
aggregations:{
manageSavedSearch : {type : "sap.ui.commons.Button", multiple :true },
layout : {type : "sap.ui.layout.VerticalLayout", multiple :false }
}
},
init : function(){
},
renderer : {
render : function(oRm, oControl) {
// Come two Times Here
var manageSavedSearch = oControl.getManageSavedSearch();
var oSavedButtonHLyt = new sap.ui.layout.VerticalLayout();
for(var index = 0 ; index < manageSavedSearch.length ; index++){
oSavedButtonHLyt.addContent(manageSavedSearch[index]);
}
oControl.setAggregation("layout",oSavedButtonHLyt);
oRm.renderControl(oControl.getAggregation("layout"));
}
}
},
onAfterRendering: function(){}
});
If I don't use any layout then It doesn't come two time in render otherwise it comes two time in render. This issues is happening from version 1.24.4. please Can I have any guidance here.
Changing aggregation(e.g. add/remove/insert/set/removeAll) invalidates the control. You should never invalidate a control during the rendering. In your case it can be an infinite loop.
To debug rendering invalidation there is a url parameter test.html?sap-ui-xx-debugRendering=true then you can see the rendering stack trace and who is responsible for the rendering.
In your code sample, there are two aggregations update. setAggregation and addContent.
Aggregation mutatators uses 3rd parameter to suppress invalidation. So following will insert the aggregation but suppress the invalidation since whole control will be rendered at the end it will not be a problem.
oControl.setAggregation("layout",oSavedButtonHLyt, true); // suppress invalidate
I guess you assume same should work for addContent
oSavedButtonHLyt.addAggregation("content", manageSavedSearch[index], true);
But it does not because here manageSavedSearch[index], so your template clone's parent is oTest initially, but you are changing the parent with addAggregation because layout will be the parent. But UI5 cannot determine automatically for the previous parent's suppress since its aggregation will be moved to somewhere else. So we go with
oControl.removeAggregation("manageSavedSearch", manageSavedSearch[index], true);
oSavedButtonHLyt.addAggregation("content", manageSavedSearch[index], true);
Here is the jsbin http://jsbin.com/rezayebada/1/edit?js,output
BTW, as you mentioned this is just an example do not take this as a reference for building composite controls.
Basically, property/aggregation/association changes invalidates the control if the control does not overwrite its mutator methods. I see it is not easy to understand what invalidates when but sap-ui-xx-debugRendering=true helps you to understand with stack trace.
This problem I was also facing, you can do one thing try using local resources
rather than online resources.

Get passed data on next page after calling "to" from NavContainer

I am on my way building a Fiori like app using SAPUI5. I have successfully built the Master page, and on item click, I pass the context and navigate to Detail page.
The context path from Master page is something like /SUPPLIER("NAME"). The function in App.controoler.js is as follows:
handleListItemPress: function(evt) {
var context = evt.getSource().getBindingContext();
this.myNavContainer.to("Detail", context);
// ...
},
But I would like to know how I can access this context in the Detail page. I need this because I need to use $expand to build the URL and bind the items to a table.
There is an example in the UI5 Documentation on how to deal with this problem using an EventDelegate for the onBeforeShow function which is called by the framework automatically. I adapted it to your use case:
this.myNavContainer.to("Detail", context); // trigger navigation and hand over a data object
// and where the detail page is implemented:
myDetailPage.addEventDelegate({
onBeforeShow: function(evt) {
var context = evt.data.context;
}
});
The evt.data object contains all data you put in to(<pageId>, <data>). You could log it to the console to see the structure of the evt object.
Please refer the "shopping cart" example in SAP UI5 Demo Kit.
https://sapui5.hana.ondemand.com/sdk/test-resources/sap/m/demokit/cart/index.html?responderOn=true
Generally, in 'Component.js', the routes shall be configured for the different views.
And in the views, the route has to be listened to. Please see below.
In Component.js:
routes: [
{ pattern: "cart",
name: "cart",
view: "Cart",
targetAggregation: "masterPages"
}
]
And in Cart.controller.js, the route has to be listened. In this example, cart is a detail
onInit : function () {
this._router = sap.ui.core.UIComponent.getRouterFor(this);
this._router.attachRoutePatternMatched(this._routePatternMatched, this);
},
_routePatternMatched : function(oEvent) {
if (oEvent.getParameter("name") === "cart") {
//set selection of list back
var oEntryList = this.getView().byId("entryList");
oEntryList.removeSelections();
}
}
Hope this helps.