UI5-在将数据加载到模型中之前,控件格式化程序执行得太早

时间:2019-06-26 14:46:06

标签: data-binding sapui5 lifecycle

我有一个Web应用程序,登录后将显示登录屏幕,左侧导航窗格。另外,在 onInit 事件期间,我调用 getUserData(),该命令收集有关用户的其他数据(例如角色,并将其保存到模型中)。 此导航的类型为 sap.tnt.NavigationListItem ,并从模型中加载(数据被硬编码在 App.controller.js 中)。在 App.view.xml 中,它看起来像这样

<tnt:NavigationListItem text="{appView>title}" 
items="{path: 'appView>items', templateShareable: true}"
visible="{path: 'appView>neededRole', formatter:'.myFormatter'}"> 

现在,我要进行改进-仅向具有足够角色的用户显示导航列表中的某些项目。 正如您在上面看到的,我为NavigationListItem的“ visible”属性设置了格式化程序。它检查显示NavigationListItem(“所需角色”)所需的角色,将其与分配给用户的角色数组进行比较,如果存在匹配项,则显示菜单项

myFormatter: function(role) {
    const oModel = this.getView().getModel('appView');
    return oModel.oData.userData.roles.some(x => x.roleId === role);
    }

问题在于,当myFormatter函数运行时,getUserData()尚未完成,并且该模型尚未包含用户的必要角色数组-因此,所有菜单项均被隐藏。我需要实现的是确保MyFormatter仅在getUserData()完成之后运行(并且myFormatter将重复运行,而getUserData必须仅运行一次)。我该如何实现? getUserData()是异步的,无论我将其放在onInit还是beforeRendering中,它都仅在myFormatter从模型中收集了空数组之后才完成。

感谢一百万

1 个答案:

答案 0 :(得分:0)

初始化视图后,格式化程序将首先运行,这是生命周期的一部分。 然后它将在每次(通过model.setProperty)显式修改“ needRole”条目时运行

在您的代码中,格式化程序似乎实际上使用了模型中的另一个数据:“角色” 因此,您可以像这样将格式化程序绑定到两个模型条目:

<tnt:NavigationListItem
  text="{appView>title}" 
  items="{
    path: 'appView>items',
    templateShareable: true
  }"
  visible="{
    parts: ['appView>neededRole', 'appView>/userData/roles'],
    formatter:'.myFormatter'
  }"> 

并将您的格式化程序修改为

myFormatter: function(role, roles) {
  return (roles || []).some(x => x.roleId === role);
}

然后,当在模型中修改一个或多个角色时,格式化程序将触发。

作为旁注:格式化程序用于格式化数据,而不是计算事物。更好的选择是直接在模型中创建一个“ entryVisible”条目,然后将其绑定到NavigationListItem上(我知道格式化程序可以完成此工作,但它们也会触发很多不需要的重新渲染)