What is metadata in Component.js? - sapui5

I am creating an app using Navigation and Routing concept and was unable to understand the metadata which needs to be specified in Component.js
What is the meaning of below :-
"controlId": "app",
"controlAggregation": "pages",
When I am checking the documentation Component.js it is mentioned as -
targetParent: "myViewId",
targetControl: "app",
targetAggregation: "pages",
Can someone explain the difference between the above two and it will be helpful what exactly it means?

With below XML view code as an example, I will elaborate about the metadata configuration.
<core:View xmlns:core="sap.ui.core" xmlns="sap.m" controllerName="Demo.view.Main" displayBlock="true" height="100%">
<App id="app">
</App>
</core:View>
App control is the root element for UI5 mobile application. It has pages aggregation as it extends from NavContainer.
targetControl: "app",
targetAggregation: "pages"
targetControl is specified with ID of control which is used to display the pages. In above XML, App control has "app" as it's ID.
So, all your views will be placed in pages aggregation of App control.
Now, you might be wondering how views can be placed in pages aggregation.
If you look at type of controls allowed in pages aggregation is Control. Any control which extends Control class can be placed in pages of App. As View is also Control it is valid to be added in pages aggregation.
So, all views in application are placed in App.
"targetParent": "myViewId"
targetParent is nothing but the view in which App control is placed.
Regarding difference between above and this
"controlId": "app",
"controlAggregation": "pages"
In newer version of SAPUI5, we specify configuration in manifest.json file instead of Component.js file. So, you will find this configuration their.
They are one and same but only with different names.

Following are the Configuration Parameters for Navigation
routes :- The routes parameter defines an array of route configurations.
config :- The config parameter defines the default values for route configuration.
view :- The view parameter contains the name of the view that is created on the first time a route is matched. To place the view in a control, use targetAggregation and targetControl. Views are only created once.
targetParent :- The target parent parameter defines the ID of the parent of the targetControl parameter.
targetControl :- Views are put into a container control, for example a shell control or a NavContainer for mobile applications, or into any other container. The targetControl parameter contains the ID of this control.
targetAggregation :- The target application parameter contains the name of an aggregation of the target control that contains views. A NavContainer, for example, has an aggregation called Pages and the shell container has Content.
subroutes :- The subroutes parameter contains an array of routes and can contain the complete route configuration. Routes that are added to subroutes may have subroutes themselves.
callback :- The callback parameter is an optional function that is executed after the route has matched.

Related

Set initial view in SAPUI5

How do I change the initial view in an SAPUI5 project? I want to change the view that is being displayed when the route pattern is ""
Should I change the rootView property in manifest?
"rootView": {
"viewName": "namespace.view.App",
"type": "XML",
"id": "app"
}
Kindly help
Thank you for everyone's assistance and suggestions.
Since the application I was editing used routing and the navigation target resolution service was configured to resolve the empty location hash to the application, I made changes to its routing configuration.
I changed the values in the "routing" configuration's "routes" where pattern was set as "" to the values of the view I wanted to display when I run the application.
Yes, You can change it there.
Replace viewName with new existing view :)
Change namespace.view.App to namespace.view.NewInitialViewName.
You can also delete App.view.xml and App.controller.js if you are not using them.

UI5 Router destroying cached views

I have a Master Details Page App where we configured the Router for the same to navigate between pages.
App.view.xml
<SplitApp id="rootControl" detailNavigate="onDetailNavigation">
</SplitApp>
manifest.json
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewPath": "master",
"controlId": "rootControl",
"viewType": "XML",
"async":"true"
},
"routes": [
{
....
},
...
"targets": {}
...
App is simple Employee CRUD app, i have configured the router with 2 routes 1 for Create/Edit and another one for Dispaly
I need to destroy the view if i navigate from one view to another view, like on start of the page show the Master Page with all the employees and detail page show display view of the employee1.
i have Edit button on the Display view, on press i navigate details page from Display view to Edit View, on this point i need to destroy the Display view from the router, which is cached.
How to achive this? or do i need to take different approch to solve the cacheing? or I should not think of Memory
tried calling destroy onDetailNavigate of SplitApp
onDetailNavigation : function(oEvent){
console.log("Split app onDetailNavigation");
oEvent.getParameter('from').destroy();
}
Which gives Error next time go back to same view again
Error: The object with ID __xmlview4 was destroyed and cannot be used anymore.
According to the comments you destroy views to save the memory allocated by your two views. I do not think this brings any real benefit. There are three possible solutions:
Stick with the current solution.
Use a single view and switch between a display and a edit fragment. An example can be found here.
Use a single view with a form with input fields. Bind the editable attribute against a model (e.g. view model) property reflecting edit or display state of the whole form or per property.
<Input value="{applicationModel>/propertyName}" editable="{viewModel>/editable}"/>
I'm using a version of the third solution. My application model (extending JSONModel) holds the application data plus a state controlling the property. The controller just calls setEditable on the application model which computes the state. Using this approach I avoid to spread the logic accross to many parts of the application.
<Input value="{applicationModel>/propertyName}" editable="{applicationModel>/Attributes/propertyName/editable}"/>
Since my Question is about the destroying the view from Router which are cached, i have followed the #boghyon comment and made some changes in my code as below which removes the pages after navigation of detail page as below
var splitApp = this.getView().byId('rootControl');
splitApp.removeDetailPage(oEvent.getParameter('from'));
and to remove the cached view from router i have wrote some logic
var router = this.getOwnerComponent().getRouter();
for(var view in router._oViews._oViews){
if( router._oViews._oViews[view].sId === oEvent.getParameter('fromId'){
delete router._oViews._oViews[view];
}
}
Which destroy the view.
By doing this which loads the views multiple times and this is not proper ways for my requirement we have follow the #matbtt answer.
Thank you both for the valueable input.

Inconsistency between documented guidelines and project templates

When I look at the Developer Guide on the SAPUI5 website this is how they declare an XML view:
<mvc:View
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc" controllerName="">
</mvc:View>
And a controller is defined like this:
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("", {
});
});
However, when I create an SAPUI5 project in Eclipse and use the option New > SAPUI5 Application Development > View, it creates a view and a controller that look like this:
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="" xmlns:html="http://www.w3.org/1999/xhtml">
</core:View>
sap.ui.controller("", {
});
On one hand, creating a view in the above manner saves me from typing the basic syntax every time. Yet on the other hand, the syntax in the developer guide (especially the controller) looks more organized to the eye.
Is there a particular reason why I should use one or the other syntax? Or can I use either approach without any difference in programming?
I am using v1.32 for development.
The first syntax (sap.ui.define) is the preferred syntax. It is also known as AMD (Async Module Declaration) syntax (see this Wiki article for more information). It wraps the module (a controller in your case) in a function call which enables
clear and easy to read declaration of the module
asynchronous invocation of the module (once all dependencies are loaded)
One library that implements this syntax is RequireJS, which is also embedded into SAPUI5 (and OpenUI5 ofc).
In their documentation about control libraries, the SAPUI5 team also recommends the AMD syntax (see here). All controls in the sap.m and sap.ui package (that I've checked) use the AMD syntax.
You can also read this interesting blog post from DJ Adams.
However it is nowhere stated (afaik) that the second syntax is deprecated. But keep in mind that it's auto generated by Eclipse because it (the UI5 plugin) is rarely maintained and therefore not up to date (they prefer developing with Node.js + grunt + Sublime/Visual Studio Code/etc.).
There you can get shorter paths for your dependencies by doing var Controller = sap.ui.core.mvc.Controller (after you required the module)
For the syntax of the view, it'll help if you understand it.
To declare an XML namespace, you need to use the following syntax :
xmlns:<namespace>="<library the namespace refers to>"
The goal of the namespace is to provide an easy and convenient way of referring to a specific library without typing out its name. In this case :
<mvc:View
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc" controllerName="">
</mvc:View>
the mvc:View component refers to the View class of the sap.ui.core.mvc library. mvc:View is the equivalent of sap.ui.core.mvc.View. You can name your namespace however you want.
The very first thing you declare in your XML view is the container for your view. This is the component which will contain all the other components of the view - the root component of the view. You can use components of different libraries as containers for your view. In this example, you are using the View component of your sap.ui.core.mvc library. In the following example:
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
controllerName="" xmlns:html="http://www.w3.org/1999/xhtml">
</core:View>
You are using the View component of your sap.ui.core library.
The following line:
xmlns="sap.m"
indicates the default library. This is the library referred to by components declared without a namespace. If later on in my view, I declare the following component:
<Input id="myinput"></Input>
The UI5 library will load the Input class from the default library, here sap.m.
Essentially, there is only one syntax for an XML view:
<myNamespace:myContainerComponent
xmlns="<my.default.library>"
xmlns:<myFirstNamespace>="my.namespace.library"
<!-- more if needed -->
controllerName="my.controller.name">
<!-- All your other components -->
</myNamespace:myContainerComponent>
I do not know enough about the possible controller syntaxes to be able to explain them. I will let someone more knowledgeable than I explain those further.
Hope this helps and makes things clearer for you.
<core:View ...> is simply wrong. Instead, write <mvc:View xmlns:mvc="sap.ui.core.mvc" ...>. For more information, see the replies and links from this GitHub issue "View class doesn't exist in the 'sap.ui.core' namespace".
sap.ui.controller is a deprecated API. The replacement is mentioned in the linked method description.
Templates / generators can be outdated too and thus, unfortunately, don't always follow best practices. No matter which tool or IDE you use to generate code, please double-check with the documented guidelines.

Zend Framework internal routing

For example, I have a page in my application called page2 that I want to access like mysite.com/page2
in the application.ini file I would have a section for it
resources.router.routes.index.route = '/page2/'
resources.router.routes.index.defaults.controller = index
resources.router.routes.index.defaults.action = page2
My question is, what if I have several pages that I want to access as children of the index controller. There must be a method that doesn't involve creating a new section in application.ini every time I have a new page...
Any advice?
This StaticRoute plugin by Ekerete Akpan uses reflection to inspect your default controller and add static routes of the form /actionname for all action methods it finds there.
This means that you don't have to add an explicit route for each of those actions. Just add an action to the default controller and the corresponding view-script in the expected place. No need to change any routing files or application.ini just to add a new top-level url.
Note, however, that since the plugin uses Reflection to inspect your default controller, using it has performance implications.

Zend Framework: Hide navigation item in menu by show in breadcrumbs

i am using Zend_Navigation i want to show the nav item in the breadcrumbs but hide it in my menu, how can i do that?
There are many choices, e.g.
You may set visible parameter to false (eg. in xml config file), then use setRenderInvisible(true/false) on the navigation helper,
You may use separate containers,
You may modify the container on the fly (getContainer(), getItemBy()…)
When using an XML config file, use an integer instead of a boolean value:
<visible>0</visible>
An issue has already been logged for this problem here.