奇迹发生了-任何程序员都会告诉你。(代替题词)下午好!一个例子很简单。有一个视图:<mvc:View
controllerName="MyController"
xmlns="sap.m"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<Button text="!" press="handlePress" />
<Table
items="{view>/list/items}"
mode="MultiSelect"
selectionChange="handleTableSelection">
<columns>
<Column>
<Text text="" />
</Column>
<Column>
<Text text="" />
</Column>
</columns>
<items>
<ColumnListItem>
<cells>
<ObjectIdentifier title="{view>id}" />
<Text text="{view>description}" />
</cells>
</ColumnListItem>
</items>
</Table>
</mvc:View>
和相同的“剔除”控制器:sap.ui.controller("MyController", {
onInit: function () {
this.__oViewModel = new sap.ui.model.json.JSONModel({
list: {
items: [
{ id: 1, description: 'one' },
{ id: 2, description: 'two' },
{ id: 3, description: 'three' }
],
selected: []
}
});
this.getView().setModel(this.__oViewModel, "view");
},
handlePress: function (oEvent) {
sap.m.MessageToast.show(this.__oViewModel.getProperty('/list/selected').join(', '));
},
handleTableSelection: function (oEvent) {
const aSelectedCtx = oEvent.getSource().getSelectedContexts(),
aSelected = aSelectedCtx.map(o => o.getObject().id);
this.__oViewModel.setProperty('/list/selected', aSelected);
}
});
在外观和行为上,所有这些都是可以预期的:
通过单击按钮,将弹出用逗号列出的选定标识符(我们将非空数组和其他ui琐事的检查留在本文范围之外)。但是想像一下,通过单击“开始吧”按钮。您不仅需要像现在一样显示所选元素的标识符,还需要从数据库中删除它们。当然,只有在用户额外确认后才需要执行这些操作。好了,这很重要-为确认对话框添加一个视图片段:ConfirmDialog.fragment.xml<core:FragmentDefinition
xmlns='sap.m'
xmlns:core='sap.ui.core' >
<Dialog
id='confirmDialog'
title=''
type='Message'
state='Warning'>
<content>
<Label text=' ?' />
</content>
<beginButton>
<Button
text=''
press='handleConfirmBtn'/>
</beginButton>
<endButton>
<Button
text=''
press='handleCancelBtn'/>
</endButton>
</Dialog>
</core:FragmentDefinition>
以及它的控制器:ConfirmDialog.controller.jssap.ui.define([
"sap/ui/base/ManagedObject"
], function (ManagedObject) {
"use strict";
return ManagedObject.extend("project.ConfirmDialog", {
constructor: function (oView, fnConfirmBtn) {
this.__oView = oView;
this.__fnConfirmBtn = fnConfirmBtn;
},
exit: function () {
delete this.__oView;
delete this.__fnConfirmBtn;
},
open: function () {
const oView = this.__oView;
let oDialog = oView.byId("confirmDialog");
if (!oDialog) {
const oFragmentController = {
handleConfirmBtn: () => {
this.__fnConfirmBtn();
oDialog.close();
},
handleCancelBtn: () => {
oDialog.close();
}
};
oDialog = sap.ui.xmlfragment(oView.getId(), "project.view.fragment.ConfirmDialog", oFragmentController);
oView.addDependent(oDialog);
}
oDialog.open();
}
});
});
如您所见,在SAP UI5 SDK的示例级别上,一切都非常经典。现在,要调用此对话框,我们重新定义主按钮的处理程序,如下所示:handlePress: function (oEvent) {
const aSelected = this.__oViewModel.getProperty('/list/selected');
this.__confirmDialog = new ConfirmDialog(this.getView(), () => {
aSelected.forEach(o => {
});
this.__confirmDialog.exit();
});
this.__confirmDialog.open();
}
就是说,在这里我们创建对话,将其将位于其上的“主”视图以及确认处理函数作为参数传递。在这里,我们来到了最有趣的地方。在继续之前,请再次检查对话框控制器代码。看到奇怪的东西了吗?没有?然后,打开跟踪模式,并选择了前两个元素,然后随时单击按钮。 handlePress: function (oEvent) {
const aSelected = this.__oViewModel.getProperty('/list/selected');
this.__confirmDialog = new ConfirmDialog(this.getView(), () => {
aSelected.forEach(o => {
});
this.__confirmDialog.exit();
});
this.__confirmDialog.open();
}
万岁,一切正常!看来,有什么收获?用户可能会感到满意,并想要删除其他内容。让我们尝试预测其动作:选择第三个元素,然后单击“ Let's Go!”: handlePress: function (oEvent) {
const aSelected = this.__oViewModel.getProperty('/list/selected');
this.__confirmDialog = new ConfirmDialog(this.getView(), () => {
aSelected.forEach(o => {
为什么[1,2],问我你。对您有好处,有人要问。当我第一次看到口译员的这种丑陋举动时,我开始默默地怀疑自己。我使用各种框架已有很长时间了,但是我从未遇到过类似的东西:众所周知,const不能保证对象和数组在存在时始终不变,但是aSelected甚至在其他任何地方都没有提及。于是他出现了,被挪用了,现在他被转移到一个回调中。但我不会长时间折磨你。这是所有js程序员都喜欢的上下文和闭包。也就是说,实际上,在第一次执行handleConfirmBtn时,我们仍然具有指向其处理程序的链接以及整个上下文(包括aSelected)。在随后的删除确认中,是她被叫。纠正错误的方法并非如此简单和明确。仅移动oFragmentController声明是不够的(在第一次调用之后,上下文丢失了)。以下是最简洁的方法(我将仅提供open方法的代码):open: function () {
const oView = this.__oView;
let oDialog = oView.byId("confirmDialog");
if (!oDialog) {
const oFragmentController = {
handleConfirmBtn: function () {
this.__fnConfirm();
oDialog.close();
},
handleCancelBtn: function () {
oDialog.close();
}
};
oDialog = sap.ui.xmlfragment(oView.getId(), "project.view.fragment.ConfirmDialog", oFragmentController);
oDialog.controller = oFragmentController;
oView.addDependent(oDialog);
}
oDialog.controller.__fnConfirm = this.__fnConfirmBtn.bind(this);
oDialog.open();
}
注意最后4条可执行代码行:这样,我将“指针”“滚动”到当前处理程序以及正确的上下文。总的来说,只需要在原始版本中添加几行即可。有可能见到一个oDialog.setBeginButton(new sap.m.Button({ text: '', press: this.__fnConfirmBtn }));
但是在这里,您知道,每次打开对话框时,都会创建一个新按钮,这不行。我还考虑了通过oDialog.getBeginButton()。AttachPress更新回调的选项,但是它只是挂起了一个附加处理程序,因此讨厌通过.detachPress删除所有可用的内容。在这里,这种冒险几乎是出乎意料的(远非第一次... ah5,ui5!)PS将函数传递给对象的构造函数,其中一个方法有一个控制器对象,该对象包含对处理函数的引用。看来可能出什么问题了?
总的来说,所描述的情况是该语言的特征,并且UI5框架根本不允许对其进行精美的解决。