【问题标题】:How to implement a confirm dialog in WinJS and return the user's choice如何在 WinJS 中实现确认对话框并返回用户的选择
【发布时间】:2014-06-12 14:13:46
【问题描述】:

使用 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(如果合适)时,然后我在控制台中看到 'proceed in弹出是真的'。我怎样才能让这些东西以正确的顺序执行?

【问题讨论】:

    标签: microsoft-metro winjs


    【解决方案1】:

    对话框是异步的;您需要等待承诺才能延迟到用户处理输入。

    最简单的做法是从您对 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
    });
    

    你的回调逻辑有一些漏洞;如果 command 没有设置,或者不是 1 或 2,你会返回什么?

    【讨论】:

    • 另外,为了符合约定,将函数重命名为doSillyMessageAsync 以强调它是一个异步操作。
    • 谢谢。我经常对这种异步的东西犯规。你的代码就像一个魅力。也感谢您对回调逻辑的评论。我只是假设,由于用户无法单击其他任何内容,因此必须设置 command 并且必须是 1 或 2。
    【解决方案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();
                        }
    
                });
    

    不过,一般来说,从你的对话框中返回承诺,以便你以后可以做事。尝试从第一个对话框启动第二个对话框时要小心,否则您会遇到令人讨厌的“拒绝访问”消息。

    【讨论】:

      猜你喜欢
      • 2011-10-26
      • 2010-10-27
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 2012-05-26
      • 1970-01-01
      • 2014-08-17
      相关资源
      最近更新 更多