在我的 UI5 应用程序中,我有一个带有表 ( sap.m.Table)的视图,由来自后端onInit挂钩的数据填充。问题是onInit每个视图实例只执行一次:
与
onBeforeRendering和onAfterRendering钩子不同,它每个 View 实例只调用一次。
并且如果用户决定离开该视图(例如,返回导航)并稍后重新打开它,则该视图onInit将不会被调用,因此不会再次检索数据,并且表格内容将不会反映可能的更改。
为确保每次打开视图时都检索数据,我尝试在 处获取数据onBeforeRendering,但此挂钩也仅调用一次。我发现,在onBeforeRendering每次打开视图时强制调用的唯一方法是将以下代码添加到onInit方法中:
onInit: function () {
this.getView().addEventDelegate({
onBeforeShow: this.onBeforeShow,
}, this);
}
Run Code Online (Sandbox Code Playgroud)
我的问题:
为什么在没有上面的代码片段的情况下onInit,onBeforeRendering每次显示视图时都不会触发?
上面的代码片段究竟做了什么?
替代技术:使用patternMatched和routeMatched。但是这三种方法中哪一种更常见呢?
- 为什么
onBeforeRendering每次显示视图时都不会触发(...) ?
我认为对“渲染”的含义存在误解。在 UI5 中,当一个控件“渲染”时,它对应的 HTML 元素正在 DOM 中被RenderManager. 即onBeforeRendering字面意思是“在render调用控件(此处:View)的功能之前”。
onBeforeRendering不不意味着它是在之前称为油漆从浏览器事件(对于这一点,现代浏览器提供高层次的API,如路口观察)。
渲染的控件可以在 DOM 中,但不能同时在视口中可见。
回到问题;之所以on*Rendering没有触发,是因为之前已经渲染了控件。当用户导航通过navTo然后再次返回时,可以看到这一点。对应的view元素已经在DOM中了,不需要render再次调用,也就没有on*Rendering触发了。
- 代码片段究竟做了什么?
Run Code Online (Sandbox Code Playgroud)this.getView().addEventDelegate({ onBeforeShow: this.onBeforeShow, }, this);
addEventDelegate向在控件(而不是由控件)上触发的事件添加一个侦听器。
例如:该视图包含诸如afterInit, beforeExit, ... 之类的事件,因为此控件(视图)触发了该事件,因此无法
执行。
这样做,因为它的发射作品在此控制。addEventDelegate({onAfterInit})afterInitaddEventDelegate({onmouseover})
这同样适用于onBeforeShow. 该视图不包含像任何事件beforeShow,afterShow等等。这些被解雇的由视图NavContainer(例如,通过<App>在其子,视图)。有关这些事件的文档可以在以下位置找到:
sap.m.NavContainerChild另见类似问题/sf/ask/3141745981/
- 替代技术:使用
patternMatched(...)。但是这三种方法中哪一种更常见呢?
我认为“三种方法”的意思是:
on*Rendering (第一种方法),on*Show (第二种方法),patternMatched(第三种方法)。答案是,一如既往,这取决于您要实现的目标。但通常,我们:
NavContainerChild如果应用程序没有路由概念(sap.ui5/routingmanifest.json中没有),请使用第二种方法(事件)。
onAfterShow如果意图是在显示视图后设置初始焦点,请使用第二种方法。请参阅如何在视图中设置初始焦点?
使用第 3 种方法获得有关正在匹配的路由模式的通知。这种方法通常用于在每次NavContainerChild显示视图 ( )时执行某些操作,例如,在导航到详细信息页面后执行Context Binding。这个怎么运作:
router.navTo()被调用时,下一个相应的视图和控制器被创建。onInit新创建的控制器中,您分配一个patternMatched 处理程序。HashChanger)注意到 URL 更改,导致 Route 触发patternMatched,您的处理程序将通过该触发被调用。请参阅下面的TL;DR。?? 个人意见:避免作为应用程序开发人员的第一种方法。避免在 inonBeforeRendering和 in 中做任何事情,onAfterRendering因为render从应用程序的角度来看,函数被调用的频率是不可预测的。对于控件开发人员来说,这些钩子是绝对必要的。但是对于应用程序开发人员来说,通常有更好的选择。
忘记on(Before|After)Rendering。改用路由中的(pattern)Matched事件:
{ // Controller
onInit: function() {
const myRoute = this.getOwnerComponent().getRouter().getRoute("routeName");
myRoute.attachPatternMatched(this.onMyRoutePatternMatched, this);
},
onMyRoutePatternMatched: function(event) {
// your code when the view is about to be displayed ..
},
}
Run Code Online (Sandbox Code Playgroud)