使用WinJS我试图向刚刚点击“继续”按钮的用户显示一条消息,表示他们没有回答问题。这会显示一个带有两个按钮的对话框(Windows.UI.Popups.MessageDialog),允许用户选择现在回答它(因此保留在无人接听的问题上)或稍后回答(因此直接进入下一个问题) 。在Javascript中,我通常可以使用一个确认对话框,它会暂停执行直到用户做出选择,然后我可以使用返回的值来决定是否显示下一个问题。在WinJS中,代码执行不会停止。这是我显示对话框的功能:
function doSillyMessage(message, title) {
var messagedialogpopup = new Windows.UI.Popups.MessageDialog(message, title);
// Add commands and set their CommandIds
messagedialogpopup.commands.append(new Windows.UI.Popups.UICommand("Answer now", null, 1));
messagedialogpopup.commands.append(new Windows.UI.Popups.UICommand("Answer later", null, 2));
// Set the command that will be invoked by default
messagedialogpopup.defaultCommandIndex = 0;
// Show the message dialog
messagedialogpopup.showAsync().done(function (command) {
if (command) {
if (command.id == 1) {
console.log('proceed in popup is false');
proceed = false;
}
else if (command.id == 2) {
console.log('proceed in popup is true');
proceed = true;
}
}
});
}
问题在于,在调用doSillyMessage的时候,代码不会等待,因此无论“proceed”变量的当前值是什么,都会继续。例如,如果在调用doSillyMessage时'proceed'的值为false,则在调用doSillyMessage之后它也是false,并且只有在稍后,当我在控制台中看到'继续'时,它才会更改为true(如果适用)弹出是真的'。如何以正确的顺序执行这些操作?
答案 0 :(得分:5)
对话是异步的;你需要等待一个承诺,以便延迟到用户处理输入。
最简单的方法是从调用showAsync返回promise。改变这个:
messagedialogpopup.showAsync().done(function (command) {
到
return messagedialogpopup.showAsync().then(function (command) {
if (command) {
if (command.id == 1) {
console.log('proceed in popup is false');
return false;
}
else if (command.id == 2) {
console.log('proceed in popup is true');
return true;
}
}
});
并将对doSillyMessage的调用更改为:
doSillyMessage().then(function (proceed) {
// proceed will be true or false
});
你的回调逻辑中有一些漏洞;如果没有设置命令,或者它不是1或2,你会返回什么?
答案 1 :(得分:2)
我最后写了一个对话帮助器来管理我的确认,提醒等。这可能对你有用:
<强>辅助强>
function confirmAsync(title, msg) {
// define confirmation buttons
var buttons = [
new Windows.UI.Popups.UICommand("Yes"),
new Windows.UI.Popups.UICommand("No")];
// make sure to return the showAsync() promise so we can chain from the call to confirmAsync
return dialogInterceptor(title, msg, buttons).showAsync();
}
function dialogInterceptor(title, msg, buttons) {
// create dialog
var dialog = new Windows.UI.Popups.MessageDialog(msg, title);
// optionally add buttons
if (buttons) {
buttons.forEach(function(button) {
dialog.commands.append(button);
});
}
// return dialog
return dialog;
}
<强>用法:强>
confirmAsync("Confirmation title text", "Are you sure you want to do something?")
.done(function (button) {
if (button.label === "Yes") {
functionToCallWhenYesIsClicked();
}
});
一般情况下,从对话框中返回承诺,以便之后可以执行操作。小心尝试从第一个对话框启动第二个对话框,否则你会发出讨厌的“拒绝访问”消息。