问题
I extended sap.ui.core.TooltipBase with mouseover event handling which is attached to some sap.ui.core.Icon in the ChartContainer:
sap.ui.define(function () {
"use strict";
return sap.ui.core.TooltipBase.extend("dvd.rl.component.ChartContainer.parts.TooltipBase.TooltipBase", {
metadata: {
events: {
"onmouseover" : {}
}
},
oView: null,
setView : function(view){
this.oView = view;
},
// the hover event handler, it is called when the Button is hovered - no event registration required
onmouseover : function() {},
});
Everythink works well, but when I click on the Icon in the ChartContainer I got this error from the TooltipBaseRenderer.js (This happens before handling of press event.):
In the TooltipBaseRenderer.js it is this line:
I have no idea what is going on there. If you will have I will be happy to hear it.
This is how I added TooltipBase to sap.ui.core.Icon:
// Add custom Icon for filter
var oFilterIcon = new sap.ui.core.Icon("filterButton", {
tooltip : "{i18n>filter}",
src : "sap-icon://filter",
press : [this.onHandleLocalFilterOpen,this]
});
// Add Icon to chart component
oChartContainer.addCustomIcon(oFilterIcon);
var oTooltipBase = new TooltipBase();
// set new TooltipBase to Icon
oFilterIcon.setTooltip(oTooltipBase);
EDITED 12:15 100117:
When I use renderer in the TooltipBase.extend:
//just inherit the renderer as it is
renderer: {},
I got this error:
So I removed renderer, and TooltipBase works when I hover over Icon. The problem is when I click on the Icon as I described higher.
回答1:
The module sap.ui.core.TooltipBase has the metadata abstract
enabled which is first purely informational, but indicates that the control has neither a renderer
-function nor any dedicated *Renderer.js file. UI5 tries to load the file TooltipBaseRenderer.js but fails ultimately --> 404 (more explained the section below). Technically, we can still instantiate TooltipBase directly, but then UI5 warns:
This is the abstract base class [...]. Do not create instances of this class, but use a concrete sub class instead. (src: TablePersoProvider which is also abstract)
Unfortunately, all publicly known sub classes of TooltipBase are now deprecated:
sap.ui.commons.RichTooltipsap.ui.commons.Calloutsap.ui.ux3.QuickView
Which leaves us with three options:
- Ditch TooltipBase altogether and pass a string instead:
oFilterIcon.setTooltip("Filters");
. The string will be displayed as a native browser tooltip on mouseover.
If this is not satisfying enough, ... Create your own subclass of TooltipBase:
- Create a custom control (e.g. named MySubTooltip.js) extending TooltipBase as you did.
- Create MySubTooltipRenderer.js (which could look like this) in the same directory. If not in the same directory, declare renderer and assign the corresponding module name to it.
The TooltipBase triggers (e.g. on mouseover) the
render
-method defined in MySubTooltipRenderer.js.Here is a minimal example of an extended TooltipBase: https://embed.plnkr.co/33zFqa/
If this all sounds like an overkill, ...
Forget tooltips and use a popover instead as encouraged by SAP:
If you want to achieve a similar behavior, use a sap.m.Popover control.
Of course, popover can be combined with
onmouseover
as well (as shown in here) but we have to take UX aspects into consideration.
Why 404?
But why was UI5 looking for a file (TooltipBaseRenderer.js) that doesn't exist at all?
According to the source code, this is what UI5 currently does when the module TooltipBase.js is retrieved:
- In the TooltipBase definition,
Control.extend
calls applySettings ultimately. - In
applySettings
, UI5 first assumes that the control's renderer name is"<control name>"
+"Renderer"
-->"TooltipBaseRenderer"
and assigns it to the control instance for later (step 3 case B). Additionally, the method also checks if the control hasrenderer
in its definition. Since the module is abstract (no renderer), the method does nothing further. - Next, in our custom control MySubTooltipBase.js,
TooltipBase.extend
is called which will also trigger theapplySettings
-method eventually. UI5 assigns"MySubTooltipBaseRenderer"
to the control instance same as step 2. Here are two 404 cases described in the question:- 404 A: No
renderer
was declared in the custom control which is fine, but there was no corresponding MySubTooltipBaseRenderer.js either. Otherwise, the RenderManager would have retrieved that external renderer and then called therender
-method e.g. on mouseover. - 404 B:
renderer
was defined but the value was invalid (renderer: {}
). In this case, UI5 tries to set an extended parent renderer as the renderer of the custom control. While trying to retrieve the renderer of the parent, UI5 reports 404 because the parent was abstract. There was no JS-file named"TooltipBaseRenderer"
(See step 2).
- 404 A: No
To sum up: Custom controls, which extend from an abstract control, have to implement their own external renderer for being able to be rendered (see example above).
At this point, we might ask: "But sap.ui.core.Control is also abstract. When extended from it, why can we still render custom controls without creating any external *Renderer.js?" --> The core control has renderer
defined in it. The value is just null
. This ensures that UI5 doesn't look for a file like ControlRenderer.js (in cases like step 3 case B). By this, the RenderManager can trigger the function that is assigned directly to the renderer
of the target custom control.
The problem is that TooltipBase doesn't even have the renderer
declared in its definition.
来源:https://stackoverflow.com/questions/41544509/tooltipbaserenderer-js-404-not-found