每次打开视图时都不会调用“onBeforeRendering”或“onAfterRendering”

Mik*_* B. 5 sapui5

在我的 UI5 应用程序中,我有一个带有表 ( sap.m.Table)的视图,由来自后端onInit挂钩的数据填充。问题是onInit每个视图实例只执行一次:

onBeforeRenderingonAfterRendering钩子不同,它每个 View 实例只调用一次。

并且如果用户决定离开该视图(例如,返回导航)并稍后重新打开它,则该视图onInit将不会被调用,因此不会再次检索数据,并且表格内容将不会反映可能的更改。

为确保每次打开视图时都检索数据,我尝试在 处获取数据onBeforeRendering,但此挂钩也仅调用一次。我发现,在onBeforeRendering每次打开视图时强制调用的唯一方法是将以下代码添加到onInit方法中:

onInit: function () {
  this.getView().addEventDelegate({
    onBeforeShow: this.onBeforeShow,
  }, this);
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 为什么在没有上面的代码片段的情况下onInitonBeforeRendering每次显示视图时都不会触发?

  2. 上面的代码片段究竟做了什么?

  3. 替代技术:使用patternMatchedrouteMatched。但是这三种方法中哪一种更常见呢?

Bog*_*ann 8

  1. 为什么onBeforeRendering每次显示视图时都不会触发(...) ?

我认为对“渲染”的含义存在误解。在 UI5 中,当一个控件“渲染”时,它对应的 HTML 元素正在 DOM 中被RenderManager. 即onBeforeRendering字面意思是“在render调用控件(此处:View)的功能之前”。

onBeforeRendering意味着它是在之前称为油漆从浏览器事件(对于这一点,现代浏览器提供高层次的API,如路口观察)。
渲染的控件可以在 DOM 中,但不能同时在视口中可见。

回到问题;之所以on*Rendering没有触发,是因为之前已经渲染了控件。当用户导航通过navTo然后再次返回时,可以看到这一点。对应的view元素已经在DOM中了,不需要render再次调用,也就没有on*Rendering触发了。


  1. 代码片段究竟做了什么?
    this.getView().addEventDelegate({
      onBeforeShow: this.onBeforeShow,
    }, this);
    
    Run Code Online (Sandbox Code Playgroud)

addEventDelegate控件(而不是由控件)上触发的事件添加一个侦听器。

例如:该视图包含诸如afterInit, beforeExit, ... 之类的事件,因为此控件(视图)触发事件,因此无法
执行。 这样做,因为它的发射作品此控制。addEventDelegate({onAfterInit})afterInit
addEventDelegate({onmouseover})

这同样适用于onBeforeShow. 该视图不包含像任何事件beforeShowafterShow等等。这些被解雇由视图NavContainer(例如,通过<App>在其子,视图)。有关这些事件的文档可以在以下位置找到:

另见类似问题/sf/ask/3141745981/


  1. 替代技术:使用patternMatched(...)。但是这三种方法中哪一种更常见呢?

我认为“三种方法”的意思是:

  • on*Rendering (第一种方法),
  • on*Show (第二种方法),
  • 以及上面提到的路由事件,如patternMatched(第三种方法)。

答案是,一如既往,这取决于您要实现的目标。但通常,我们:

  • NavContainerChild如果应用程序没有路由概念(sap.ui5/routingmanifest.json中没有),请使用第二种方法(事件)。

  • onAfterShow如果意图是在显示视图后设置初始焦点,请使用第二种方法。请参阅如何在视图中设置初始焦点?

  • 使用第 3 种方法获得有关正在匹配的路由模式的通知。这种方法通常用于在每次NavContainerChild显示视图 ( )时执行某些操作,例如,在导航到详细信息页面后执行Context Binding。这个怎么运作:

    1. router.navTo()被调用时,下一个相应的视图和控制器被创建。
    2. onInit新创建的控制器中,您分配一个patternMatched 处理程序
    3. 在导航时,URL 哈希值会改变。路由器(在 内部HashChanger)注意到 URL 更改,导致 Route 触发patternMatched,您的处理程序将通过该触发被调用。请参阅下面的TL;DR
  • ?? 个人意见:避免作为应用程序开发人员的第一种方法。避免在 inonBeforeRendering和 in 中做任何事情,onAfterRendering因为render从应用程序的角度来看,函数被调用的频率是不可预测的。对于控件开发人员来说,这些钩子是绝对必要的。但是对于应用程序开发人员来说,通常有更好的选择。


TL; 博士

忘记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)