【问题标题】:jQuery Deferred and Dialog boxjQuery 延迟和对话框
【发布时间】:2012-11-25 09:15:41
【问题描述】:
function ValidateField(){
var bAllow= true;

    //some checking here

if (bAllow == true && apl.val().trim() == "")
{ 
    showDialog(); 
    showDialog().done(function() {
        return true; // wanna return true, but not success
    }).fail(function() {
        return false; //wanna return false, but not success
    });
    return false; //stop it to execute to next line
}
return bAllow; //success return }

function showDialog(){
var def = $.Deferred();
var modPop = '<div id="diaCom" title="Information?"><p>something something</p></div>';
$("#diaCom").remove();
$(modPop).appendTo('body');
$("#diaCom").dialog({
    resizable: false,
    draggable: false,
    height:150,
    width:300,
    modal: true,
    buttons: {
        "Ok": function() {  
            def.resolve();
            $(this).dialog("close");

        },
        "Cancel": function() {
            def.reject();
            $(this).dialog("close");

        }
    }
});

return def.promise();
}
//on click
if (validateField() == true){
        //do something
 }else{
        //do something
  }

大家好,有机会返回价值吗?我希望通过 showDialog().done() 返回 true 和 false 并且 validatefield() 函数失败,但它不能按我想要的方式工作,我不能分配给 bAllow 因为我已经有一个 return false 持有执行下一行的对话框,知道吗?或者这样做是正确的?

【问题讨论】:

  • 您将无法使 Javascript 等待延迟对象的完成,因此以后无法return。我不确定如何“解决”这个问题,但我认为方法是重新组织你的代码/逻辑
  • 不,您不能从异步任务同步返回。相反,通过延迟!
  • 所以意味着我传递给另一个函数,n 使用另一个函数来进行验证检查而不是同一个函数?可以告诉我一些正确的方法吗?创建一个全局变量,根据deferend将其设置为true/fase,然后在另一个函数中,使用全局变量进行检查,然后使用函数返回true/false?我还是新手,只是通过谷歌搜索并解开它,出来这样的东西
  • 我想不出任何代码可以使用它进行与我想要的相同的检查
  • 猜猜我放弃了使用 Dialog 来返回任何东西,而不是返回,我删除了取消按钮,所以会显示一条消息,说由于满足某些条件需要再次单击提交按钮,用户需要再次点击按钮才能提交表单

标签: javascript jquery jquery-ui


【解决方案1】:

嗯,这可以工作。

你的对话框函数... showDialog()

function confirmation(question) {
    var defer = $.Deferred();
    $('<div></div>')
        .html(question)
        .dialog({
            autoOpen: true,
            modal: true,
            title: 'Confirmation',
            buttons: {
                "Yes": function () {
                    defer.resolve(true); //answer
                    $(this).dialog("close");
                },
                "No": function () {
                    defer.resolve(false); //answer
                    $(this).dialog("close");
                }
            },
            close: function () {
                $(this).remove(); //removes this dialog div from DOM
            }
        });
    return defer.promise();
}

然后是你使用函数的代码...

function onclick(){
    var question = "Do you want to start a war?";
    confirmation(question).then(function (answer) {
        if (answer) {
            alert("this is obviously " + answer);//TRUE
        } else {
            alert("and then there is " + answer);//FALSE
        }
    });
}

对于大多数人来说,这似乎是错误的。但是总有一些情况,你不能不从 JQuery Dialog 中返回。

这将基本上模仿 confirm() 函数。但是有丑陋的代码和漂亮的确认框外观:)

我希望这可以帮助一些人。


**

编辑:Bootstrap 3 解决方案

**
我现在正在使用 [NakuPanda's][1] 引导库,效果非常好。基本上与 JQueryUI 相同,但在 Bootstrap UI 中。
function bsConfirm(question) {
    var defer = $.Deferred();
    BootstrapDialog.show({
        type: BootstrapDialog.TYPE_PRIMARY,
        title: 'Confirmation',
        message: question,
        closeByBackdrop: false,
        closeByKeyboard: false,
        draggable: true,
        buttons: [{
            label: 'Yes',
            action: function (dialog) {
                defer.resolve(true);
                dialog.close();
            }
        }, {
            label: 'No',
            action: function (dialog) {
                defer.resolve(false);
                dialog.close();
            }
        }],
        close: function (dialog) {
            dialog.remove();
        }
    });
    return defer.promise();
}
function bsAlert(error, message) {
    BootstrapDialog.show({
        type: error ? BootstrapDialog.TYPE_DANGER : BootstrapDialog.TYPE_SUCCESS,
        title: error ? "Error" : "Success",
        message: message,
        closeByBackdrop: false,
        closeByKeyboard: false,
        draggable: true,
        buttons: [{
            label: 'OK',
            action: function (d) {
                d.close();
            }
        }]
    });
}

并使用它(几乎相同的方式)

bsConfirm("Are you sure Bootstrap is what you wanted?").then(function (answer) {
    if (answer) {
        bsAlert("Well done! You have made the right choice");
    } else {
        bsAlert("I don't like you!");
    }
});

【讨论】:

  • 我多次使用类似的方法。注意:您的代码会将配置的 &lt;div&gt;&lt;/div&gt; 留在 DOM 中 - 您需要在对话框的 close 处理程序中使用 $(this).dialog('destroy').remove()
  • @Pierre:我是否必须为 Deferred 添加任何额外的库并承诺工作?
  • @ChandniShah 只有 Jquery 1.5+ 它是一个内置函数。请参阅https://api.jquery.com/category/deferred-object/ 了解更多信息
  • @Pierre:感谢您的帮助。但在我的情况下,这个解决方案不起作用。它不会等到我点击是或否按钮。
  • @ChandniShah 请确保您希望它继续使用的代码位于confirmation("LA?").then(function(){ ... Your code here ... }); 内的function 语句部分中
【解决方案2】:

我已经创建了this JSFIDDLE 并更改了布尔解析,因为它正在爆炸。谢谢,皮埃尔!这为我节省了很多时间。

javascript:

function confirmation(question) {
var defer = $.Deferred();
$('<div></div>')
    .html(question)
    .dialog({
        autoOpen: true,
        modal: true,
        title: 'Confirmation',
        buttons: {
            "Yes": function () {
                defer.resolve("true");//this text 'true' can be anything. But for this usage, it should be true or false.
                $(this).dialog("close");
            },
            "No": function () {
                defer.resolve("false");//this text 'false' can be anything. But for this usage, it should be true or false.
                $(this).dialog("close");
            }
        },
        close: function () {
            //$(this).remove();
            $(this).dialog('destroy').remove()
        }
    });
return defer.promise();
};

function onclick(){
var question = "Do you want to start a war?";
confirmation(question).then(function (answer) {
    console.log(answer);
    var ansbool = (String(answer) == "true");
    if(ansbool){
        alert("this is obviously " + ansbool);//TRUE
    } else {
        alert("and then there is " + ansbool);//FALSE
    }
});
}

$("#item").on('click', onclick);

HTML:

<button id="item">Hello, click me.</button>

【讨论】:

    【解决方案3】:

    为什么不使用reject 方法代替resolve("false")。然后,您将能够将对象作为参数传递。 假设您有多个输入字段集,每个字段集都有一个删除按钮:

     function confirmation(question,obj) {
        var defer = $.Deferred();
        $('<div></div>')
            .html(question)
            .dialog({
                autoOpen: true,
                modal: true,
                title: 'Confirmation',
                buttons: {
                    "Oui": function () {
                        defer.resolve(obj);// pass the object to delete to the defer object
                        $(this).dialog("close");
                    },
                    "Non": function () {
                        defer.reject();//reject, no need to pass the object
                        $(this).dialog("close");
                    }
                },
                close: function () {
    
                    $(this).dialog('destroy').remove()
                }
            });
        return defer.promise();
    }
    
    $(document).on("click", ".btn-suppr",function (){// all delete buttons having a class btn-suppr
    
    var question = "Are you sure to delete this fieldset ?";
    confirmation(question,$(this)).then(function (obj) {
    
                                    obj.parent('fieldset').remove(); // remove the parent fieldset of the delete button if confirmed
    
                                });
                            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 2011-05-11
      • 2020-09-28
      • 2011-07-29
      相关资源
      最近更新 更多