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

UI5 - control formatter is executed too soon, before the data is loaded into model

我有一个 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 ('needed role') 所需的角色,将其与分配给用户的角色数组进行比较,如果匹配,则显示菜单项

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

问题是当 myFormatter 函数为 运行ning 时,getUserData() 尚未完成并且模型还没有包含必要的用户角色数组 - 原因是所有菜单项目被隐藏。我需要实现的是确保 MyFormatter 运行 仅在 getUserData() 完成之后(虽然 myFormatter 将重复 运行,但 getUserData 必须 运行 一次)。我怎样才能实现它? getUserData() 是异步的,无论我将它放在 onInit 还是 beforeRendering 中,它只会在 myFormatter 从模型中收集到空数组后才完成。

万分感谢

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

在您的代码中似乎您的格式化程序实际上使用了模型中的另一个数据:'roles' 所以你可以像这样将你的格式化程序绑定到两个模型条目:

<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 上(我知道格式化程序可以完成这项工作,但它们也会触发很多您不需要的重新渲染)