如何限定事件处理程序的形式参数以用于 Fragment.load 承诺解决方案?
How to scope an event handler's formal parameter for use in a Fragment.load promise resolution?
如何限定事件处理程序的形式参数以用于 Fragment.load 承诺解析?
我构建了一个包含 sap.m.MessagePopover 的 XML 片段。我要求 MessagePopover 能够通过触发事件的任何按钮或控件打开。我在基本控制器中创建了事件处理程序。按照最佳实践,事件处理程序仅在事件发生时才使用 sap.ui.require 加载组件和片段定义。 Fragment.load promise 解析然后通过触发事件的控件打开 MessagePopover。我的问题是我必须在控制器的全局变量中创建对事件源的引用,以便在 sap.ui.require/Fragment.load 范围内使用它。
我的问题是是否可以使用一些 promise/callback 魔法使 oEvent 在 Fragment.load 承诺解决方案中可见,这样我就不必在控制器中创建全局引用?
P.S。请忽略片段应存储在控制器变量中以供后续调用使用的事实。
这是片段文件
<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}" />
以下是将显示片段的事件处理程序。这是我希望在 .then()
内提供 oEvent 的地方
/**
* 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 implementation(第 74-78 行)中看到它。
您可以只使用一个局部变量作为事件源,而不是创建一个 属性 到 this 对象,它将作为闭包的一部分在 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));
}
如何限定事件处理程序的形式参数以用于 Fragment.load 承诺解析?
我构建了一个包含 sap.m.MessagePopover 的 XML 片段。我要求 MessagePopover 能够通过触发事件的任何按钮或控件打开。我在基本控制器中创建了事件处理程序。按照最佳实践,事件处理程序仅在事件发生时才使用 sap.ui.require 加载组件和片段定义。 Fragment.load promise 解析然后通过触发事件的控件打开 MessagePopover。我的问题是我必须在控制器的全局变量中创建对事件源的引用,以便在 sap.ui.require/Fragment.load 范围内使用它。
我的问题是是否可以使用一些 promise/callback 魔法使 oEvent 在 Fragment.load 承诺解决方案中可见,这样我就不必在控制器中创建全局引用?
P.S。请忽略片段应存储在控制器变量中以供后续调用使用的事实。
这是片段文件
<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}" />
以下是将显示片段的事件处理程序。这是我希望在 .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 implementation(第 74-78 行)中看到它。
您可以只使用一个局部变量作为事件源,而不是创建一个 属性 到 this 对象,它将作为闭包的一部分在 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));
}