promise - 如何限定事件处理程序的形式参数以用于 Fragment.load 承诺解析?
问题描述
如何限定事件处理程序的形式参数以用于 Fragment.load 承诺解析?
我已经构建了一个包含 sap.m.MessagePopover 的 XML 片段。我要求 MessagePopover 能够被任何触发事件的按钮或控件打开。我在基本控制器中创建了事件处理程序。遵循最佳实践,事件处理程序仅在事件发生时才使用 sap.ui.require 加载组件和片段定义。Fragment.load 承诺解析然后通过触发事件的控件打开 MessagePopover。我的问题是我必须在控制器的全局变量中创建对事件源的引用,才能在 sap.ui.require/Fragment.load 范围内使用它。
我的问题是是否可以使用一些承诺/回调魔法让 oEvent 在 Fragment.load 承诺解决方案中可见,所以我不必在控制器中创建全局引用?
PS 请忽略片段应该存储在控制器变量中以供后续调用使用的事实。
这是片段文件
<core:FragmentDefinition
xmlns="sap.m"
xmlns:core="sap.ui.core">
<MessagePopover
items="{messages>/}">
<MessageItem
activeTitle="{/useActiveTitle}"
description="{i18n>DESCRIPTION}"
subtitle="{i18n>SUBTITLE}"
title="{messages>message}"
type="{messages>type}" />
</MessagePopover>
</core:FragmentDefinition>
在我的测试视图中,我有以下按钮。
<Button
id="btnViewMessages"
icon="sap-icon://message-popup"
press=".onMessageButtonPress"
text="{= ${messages>/}.length }"
tooltip="{i18n>VIEW_MESSAGES}"
type="Emphasized"
visible="{= ${messages>/}.length > 0}" />
以下是将显示片段的事件处理程序。这是我希望在其中提供 oEvent 的地方.then()
/**
* Handle a control event to display a MessagePopover next to the control.
* @function
* @public
* @param {sap.ui.base.Event} [oEvent]
*/
onMessageButtonPress: function (oEvent) {
// This is where I must to create a reference to the source for later use
this._oSource = oEvent.getSource();
sap.ui.require([
"sap/ui/core/Fragment"
], function(Fragment) {
Fragment.load({
name: "testControls.view.fragments.MessagePopover"
})
.then(function (oFragment) {
this.getView().addDependent(oFragment);
// Here I would like to somehow scope oEvent to be able to use it here
// instead of having to use the controller's global variable _oSource.
oFragment.openBy(this._oSource);
}.bind(this));
}.bind(this));
}
为了进行测试,您可以在控制器中使用以下 onInit 来为 MessagePopover 提供可用的消息。
onInit: function () {
// Set the model for the view
var oViewModel = new JSONModel();
oViewModel.setData({
"useActiveTitle": true
});
this.getView().setModel(oViewModel);
// Setup the MessageManager along with view's message model.
this._MessageManager = sap.ui.getCore().getMessageManager();
this.getView().setModel(this._MessageManager.getMessageModel(), "messages");
this._MessageManager.registerObject(this.getView(), true);
this._MessageManager.addMessages(
new Message({
message: "Enter a valid number for seconds to display busy UI",
type: library.MessageType.Error,
target: "/Dummy",
processor: this.getView().getModel()
}));
this._MessageManager.addMessages(
new Message({
message: "Fix all errors to coninue",
type: library.MessageType.Info,
target: "/Dummy",
processor: this.getView().getModel()
}));
}
为了重申我的期望,我想使用oFragment.openBy(oEvent.getSource())
控制器的全局变量 _oSource 来代替。
解决方案
不幸的是,事件实例在所有处理程序都有机会处理它之后被重置。因此,当您的 Fragment 承诺被解决时,事件实例由 SAPUI5 ObjectPool 模块重置:您可以在Event.js 实现中看到它(第 74-78 行)。
你可以只使用一个局部变量作为事件源,而不是为这个对象创建一个属性,它将作为闭包的一部分在 Promise 解析中可用:
onMessageButtonPress: function (oEvent) {
// This is where I must to create a reference to the source for later use
var oSource = oEvent.getSource();
sap.ui.require([
"sap/ui/core/Fragment"
], function(Fragment) {
Fragment.load({
name: "testControls.view.fragments.MessagePopover"
})
.then(function (oFragment) {
this.getView().addDependent(oFragment);
// Here I would like to somehow scope oEvent to be able to use it here
// instead of having to use the controller's global variable _oSource.
oFragment.openBy(oSource);
}.bind(this));
}.bind(this));
}
推荐阅读
- regex - 匹配名称的正则表达式模式
- firebase - Firebase 函数的目标部署
- javascript - MongoDB 文档已添加但未在网站上显示(无需刷新)
- c# - Picturebox 出现问题并尝试更新图像
- arrays - 。包括?数组[rand(array.length)]
- java - 使用具有不同关联大小的 LRU 的处理器缓存的通用实现
- javascript - MongoDB 从满足 $in 的文档中选择第一个结果
- c++ - C++ 创建、打开和保存到文件并循环显示
- android - 如何在kotlin中使用相同的List对sortBy和groupBy进行排序
- c# - 如何在 C# 中更改菜单条所有部分的颜色