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

问题描述 投票:4回答:3

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

[每个View实例仅调用一次,与onInitonBeforeRendering挂钩不同。

并且如果用户决定离开此视图(例如,向后导航)并在以后重新打开,则不会调用onAfterRendering,因此不会再次检索数据,并且表内容将不会反映出可能的更改。

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

onInit

我的问题:

  1. 为什么onInit: function () { this.getView().addEventDelegate({ onBeforeShow: this.onBeforeShow, }, this); } 中没有上面的代码段,每次显示视图时都不会触发onInit

  2. 上面的代码段到底是做什么的?

  3. 替代方法:使用onBeforeRenderingpatternMatched。但是,这三种方法中哪一种比较常见?

sapui5
3个回答
5
投票
  1. 为什么每次显示视图时都不会触发patternMatched

我认为对“渲染”的含义有误解。在UI5中,当某些东西在“渲染”中时,routeMatched正在(重新)编写一个完整的新DOM元素。即在调用控件(视图)的routeMatched功能之前先调用onBeforeRenderingRenderManager

它确实not表示它是在浏览器paints元素到屏幕之前调用的(为此,现代浏览器提供了本机API,例如onBeforeRendering)。

回到问题;之所以没有触发render,是因为该控件之前已经呈现过。当用户通过src导航然后再次返回时可以看到。相应的视图元素已经在DOM中,因此无需再次调用Intersection Observer,这意味着无需触发on*Rendering


  1. 该代码段的确切作用是什么?

    navTo

[render将侦听器添加到在控件[[on上触发的事件(由控件<< not >>)。例如:on*Rendering,例如onInit: function () { this.getView().addEventDelegate({ onBeforeShow: this.onBeforeShow, }, this); } addEventDelegate,...由于view contains events被此控件(视图)触发,因此无法执行afterInit。执行beforeExit是有效的,因为它已触发此控件。addEventDelegate({onAfterInit})同样。该视图不包含任何事件,例如afterInitaddEventDelegate({onmouseover})等。这些事件由onBeforeShow在视图中触发(例如,其子视图中的beforeShow被激发)。有关这些事件的文档可以在以下位置找到:

API参考:afterShow

主题

NavContainer

另请参见类似的问题
    <App>
  • 另一种方法:使用sap.m.NavContainerChild(...)。但是,这三种方法中哪一种比较常见?

  • 通过“三种方式”,我想你的意思是:
    sap.m.NavContainerChild(第一种方法),
      Events Fired on the Pages(第二种方法),
    1. 以及上述路由事件,例如Why does onBeforeFirstShow work?(第3种方法)。

    答案和往常一样,

      取决于您要实现的目标。但是
    • 通常,我们:
    • 如果应用程序没有路由概念(manifest.json中没有patternMatched,请使用第二种方法(on*Rendering事件)。
    • 如果要在显示视图后设置初始焦点,请对on*Show使用第二种方法。参见patternMatched

      使用第三种方法来获取有关匹配的路由模式的通知。这种方法通常用于每次显示视图(NavContainerChild)时执行某项操作,例如,导航到详细信息页面后执行
    • sap.ui5/routing。工作原理:
  • 当调用onAfterShow时,将创建下一个相应的视图和控制器。
  • 在新创建的控制器的How to Set Initial Focus in a View?中,分配一个NavContainerChild Context Binding
  • 导航时,URL哈希值将改变。路由器(在内部router.navTo())注意到URL的更改,从而导致路由触发onInit,您的处理程序将通过该路由触发。请参阅下面的[[TL; DR

      ⚠️个人观点:避免采用
    1. application
    2. 开发人员的第一种方法。避免在patternMatchedhandler中执行任何操作,因为从应用程序的角度来看,HashChanger函数的调用频率是无法预测的。对于
    3. control
    4. 开发人员,这些挂钩是绝对必要的。但是对于应用程序开发人员来说,通常会有更好的选择。
  • TL; DR
  • HashChanger
  • 忘记patternMatched


    问题3:

    patternMatched将在URL或onBeforeRendering方法上与您的路由器匹配时被命中。 

    [onAfterRendering将在与render相同的情况下以及其子路线被导航到的情况下受到打击。

    想象一下,您对路径
    A
    拥有主视图,并且对路径

    B

    的详细了解。如果用户直接导航到路线B,则渲染与路线

    B

    关联的目标以及与路线

    A

    关联的目标是有意义的。

    总结:

    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 .. }, :直接路由匹配

    on(Before|After)Rendering

      此路由器中的路由模式。
  • 其子路径的模式。

    其嵌套路线的模式。发生这种情况时,将使用嵌套路由的实例设置patternMatched参数。

    1. 您应该使用
  • router.navTo
  • 每当您的路由配置中匹配路由模式时,都会触发此路由事件。在上面的示例中,每次通过导航加载路线时都会调用函数routeMatched
  • patternMatched

  • 2
    投票
    A
    © www.soinside.com 2019 - 2024. All rights reserved.