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.
Related
I am trying to find out if anyone has an approach to automated UI testing on Material UI components.
Material UI elements are rendered as nested divs with very little unique id information, for example:
<div data-reactroot style="...">
<div style="...">
<div style="...">
</div>
</div>
</div>
The nested div structure makes using traditional location methods difficult if not impossible - (Selenium and Watir), id, name, class, etc.
Using react devtools, one can see a much clearer picture of how the page is structured, but I am not yet able to access the React "DOM" to locate elements.
Any ideas or help would be appreciated.
Added example:
Sliders
I can't come up with an example that is more descriptive than the one above, could literally be 10 layers of nested divs without any text.
There is no general method I'm aware of, unfortunately.
Some of the components already have ids, which allows you to use a css selector like #my-component input (which is usually enough to get an exact field), others have custom class names to be added (like AutoComplete - popoverProps) which allows you to use a similar selector.
Good news is that every MaterialUI component provides className, which can be used to locate elements (at least partially) - details can be found at http://www.material-ui.com/#/customization/styles
Also id field works quite often, even when not documented.
At the last resort (if detection by class + other css selector parts is not sufficient) you can fall back to XPath expression using element text - for example, I use //span[#class="menu-item"][.//div[contains(text(),"${itemName}")]] for matching menu items. It matches things declared as <MenuItem primaryText={itemName} className="menu-item">
If this isn't possible please let me know!
I'm hoping there's a solution to what I'm asking.
I need to move the Next/Prev buttons, located in the pagenavigation plugin to after the <jdoc:include type="component" />; Basically render it anywhere in my templates' index.php?
Is there any way to do this?
This is the code that renders the pagination:
<?php
if (!empty($this->item->pagination) && $this->item->pagination && $this->item->paginationposition && !$this->item->paginationrelative):
echo $this->item->pagination;
?>
<?php endif; ?>
As you can see the pagination is part of the item. As you can see if you look at the pagenavigation content plugin the pagination values are created in response to the onContentBeforeDisplay event. The plugin is hard coded to only work for articles in the single article view.
So to use it in a different component you would really need to create a second plugin for that component (or you could do any component or anything besides the single article view, that all would be easy to code using context).
To locate it in a different place in the single article view you would have to move the block of code to the desired location in the layout. Potentially you could also use css to locate the rendering of the block somewhere else on the page. (But more on this at the bottom.)
Unfortunately (but nor surprisingly given its name) onContentBeforeDisplay comes really late, in the view (unlike with pagination in the backend).
I always find it confusing because this frontend "pagination" property controlled by this plugin has nothing to do with backend pagination which is controlled by a JPagination object. I believe if is because of backward compatibility all the way to 1.0. ALso because the template chrome for pagination chrome are called pagination.php.
That leads me to the next thing I'll mention. You can make a file pagination.php and put it in the html folder of your template. You can see an example of this in the core template protostar. THat's where you would do the CSS or whatever other tricks you want to do to make the pagination do what you want. I think if you work hard enough at it (possibly using javascript or possibly calling that file from a module) you can pretty much achieve whatever you want.
Code here: http://plnkr.co/edit/PfOgEDphwrnSXwatB6Yo?p=preview
I have a collection of products that I need to show on the screen.
I load the JSON model and set it as a general model and I have an aggregation binding on a grid's content
var productTemplate = new sap.ui.view({
viewName: "view.Product",
type: sap.ui.core.mvc.ViewType.HTML
});
grid.bindAggregation("content", "/", productTemplate);
The productTemplate is a html view as you can see:
<div id="mySimpleTemplate" data-type="text/x-handlebars-template">
<h3>Product</h3>
<b>{{text path="name"}}</b>
</div>
<script>
sap.ui.template();
</script>
There are two issues:
The relative binding is not working. The name of the product is not displayed. If I use absolute binding {{text path="/3/name"}} the name will be displayed ok.
Second big issue is that the templating is only applied for the FIRST element. Afterwards the html view is interpreted as simple text
Where do I make the mistake?
Also, the documentation on HTML template is quite limited on SAP official site. Can you provide some tutorials, examples links?
Thank you!
First of all, I am no expert on templating in SAPUI5.
That being said, I think you are mixing two concept here: Views and Templates.
With my missing expertise, I can't really tell you about the ideas and concepts being this. However I did manage to get your example to work:
Rename your template file to view/Product.view.tmpl.
Remove the script tag in it, so it only contains the template.
In the Main view use new sap.ui.templateview("view.Product"); to create a TemplateView based on your template.
Please also see the updated Plunker.
Please can somebody clarify when I would use an ion-nav-view opposed to an ion-view? I am learning AngularJS/Ionic (I have a basic understanding of AngularJS; and would like to use Ionic to enhance it).
I understand the ion-nav-view implements the AngularUI Router service(?) which is a must in order to have nested views within views. But the documentation does not make clear where I should be using one or the other?
All the documentation states for ion-view is:
A container for content, used to tell a parent ionNavBar about the current view.
But I have seen an ion-view used outside navbar interface.
So what gives?
ion-nav-view is the place where your ion-views get injected to.
You can see ion-nav-view as the frame where your paint, the ion-view, is gonna be painted on by the $stateProvider.
Open the template menu.html
Search for
ion-nav-bar class="bar-stable"
and change it to
ion-nav-bar class="bar-stable bar-royal"
i'm trying to create a node in the Zend_Navigation tree that is just used for organizing the links within it. therefore it would NOT require an anchor tag when rendered and not show up in the breadcrumb. anyone know how to make this happen?
Not really sure what your're after. I assume that you use navigation.xml in application/config folder to organize your navigation. Then you could provide a dummy navigation element and disable it using css:
<all>
<label>Home</label>
<resource>default:Home</resource>
<module>default</module>
<class>dummy</class>
</all>