如何使用 promises 在 JS 中实现自定义 'confirm' 提示符
How to implement a custom 'confirm' prompt in JS using promises
这是基本代码
$(".add-item").click(function() {
var flag;
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
if (confirm("Add with a flag?") == true) {
flag = true
} else {
flag = false
}
}
addItem(flag)
})
不过,我想做的是构建一个强大的模式,其中包含有关如何回答所提出的 'Add with a flag?' 问题的具体说明。在模式中,'Yes' 与 'No' 将有 2 个按钮元素。因此,将其视为基本模态(使用 Bootstrap):
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="flag_modal" aria-hidden="true" id="flag_modal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title serif text-center">
Add with a flag?
</h2>
</div>
<div class="modal-body">
<!-- detailed instructions -->
<button id="yes" class="btn btn-lg">Yes</button>
<button id="no" class="btn btn-lg">No</button>
</div>
</div>
</div>
</div>
和默认的confirm
alert一样,UX是当add-item
被点击时,如果不包含的逻辑计算出ask_about_flag
为真,就会弹出这个modal,并且在用户选择 #yes
或 #no
来设置标志的值之前,代码不会继续调用 addItem
。
然而,也有可能在点击 add-item
时,未包含的逻辑计算出 ask_about_flag
为假,因此模态框不显示并调用 addItem
( flag = null
在这种情况下)。
因此,我认为代码组织将 addItem
函数调用保留在 add-item
单击中而不是将其下推到按钮处理程序中是有意义的(下面的代码很清楚会工作)
$(".add-item").click(function() {
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
$("#flag_modal").show()
}
addItem()
})
$("#yes").click(function() {
addItem(true)
})
$("#no").click(function() {
addItem(false)
})
我想做一些事情,例如:
$(".add-item").click(function() {
var flag;
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
// pop up modal to ask user to set value of flag
}
// wait to execute until value of flag is set, if needed
addItem(flag)
})
似乎 Promises
是正确的方法(如果不是,请告诉我!),但这对我来说仍然很新,所以我试了一下下面的方法。一直工作到我单击 yes
或 no
按钮时我得到 Uncaught TypeError: promise.resolve is not a function
var promise; // declare so that it's available both from within `add-item` and `button` handlers
$(".add-item").click(function() {
promise = new Promise(function(resolve, reject) {
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
$("#flag_modal").modal("show")
} else {
resolve(null)
}
})
promise.then(function(flag) {
// flag is the parameter passed to resolve
addItem(flag)
})
})
$("#yes").click(function() {
promise.resolve(true)
})
$("#no").click(function() {
promise.resolve(false)
})
FIDDLE: https://jsfiddle.net/0g76ce5s/
实际上,我更喜欢你的第一种方法,因为它更关注分离。
但是如果你想做 Promise 方法,你需要传递的是 resolve
函数而不是 Promise。
示例如下:
var resolveGlobal; // declare so that it's available both from within `add-item` and `button` handlers
$(".add-item").click(function () {
promise = new Promise(function (resolve, reject) {
var ask_about_flag = true;
if (ask_about_flag) {
$("#flag_modal").modal("show");
resolveGlobal = resolve;
} else {
resolve(null);
}
});
promise.then(function (flag) {
// flag is the parameter passed to resolve
addItem(flag);
});
});
$("#yes").click(function () {
resolveGlobal(true);
});
$("#no").click(function () {
resolveGlobal(false);
});
function addItem(flag) {
console.log(flag);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
</head>
<body>
<div id="box">
<div
class="modal fade"
tabindex="-1"
role="dialog"
aria-labelledby="flag_modal"
aria-hidden="true"
id="flag_modal"
>
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title serif text-center">
Add with a flag?
</h2>
</div>
<div class="modal-body">
<!-- detailed instructions -->
<button id="yes" class="btn btn-lg">Yes</button>
<button id="no" class="btn btn-lg">No</button>
</div>
</div>
</div>
</div>
<button class="add-item">Add item</button>
</div>
</body>
</html>
这是基本代码
$(".add-item").click(function() {
var flag;
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
if (confirm("Add with a flag?") == true) {
flag = true
} else {
flag = false
}
}
addItem(flag)
})
不过,我想做的是构建一个强大的模式,其中包含有关如何回答所提出的 'Add with a flag?' 问题的具体说明。在模式中,'Yes' 与 'No' 将有 2 个按钮元素。因此,将其视为基本模态(使用 Bootstrap):
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="flag_modal" aria-hidden="true" id="flag_modal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title serif text-center">
Add with a flag?
</h2>
</div>
<div class="modal-body">
<!-- detailed instructions -->
<button id="yes" class="btn btn-lg">Yes</button>
<button id="no" class="btn btn-lg">No</button>
</div>
</div>
</div>
</div>
和默认的confirm
alert一样,UX是当add-item
被点击时,如果不包含的逻辑计算出ask_about_flag
为真,就会弹出这个modal,并且在用户选择 #yes
或 #no
来设置标志的值之前,代码不会继续调用 addItem
。
然而,也有可能在点击 add-item
时,未包含的逻辑计算出 ask_about_flag
为假,因此模态框不显示并调用 addItem
( flag = null
在这种情况下)。
因此,我认为代码组织将 addItem
函数调用保留在 add-item
单击中而不是将其下推到按钮处理程序中是有意义的(下面的代码很清楚会工作)
$(".add-item").click(function() {
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
$("#flag_modal").show()
}
addItem()
})
$("#yes").click(function() {
addItem(true)
})
$("#no").click(function() {
addItem(false)
})
我想做一些事情,例如:
$(".add-item").click(function() {
var flag;
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
// pop up modal to ask user to set value of flag
}
// wait to execute until value of flag is set, if needed
addItem(flag)
})
似乎 Promises
是正确的方法(如果不是,请告诉我!),但这对我来说仍然很新,所以我试了一下下面的方法。一直工作到我单击 yes
或 no
按钮时我得到 Uncaught TypeError: promise.resolve is not a function
var promise; // declare so that it's available both from within `add-item` and `button` handlers
$(".add-item").click(function() {
promise = new Promise(function(resolve, reject) {
var ask_about_flag = // some logic ...
if (ask_about_flag == true) {
$("#flag_modal").modal("show")
} else {
resolve(null)
}
})
promise.then(function(flag) {
// flag is the parameter passed to resolve
addItem(flag)
})
})
$("#yes").click(function() {
promise.resolve(true)
})
$("#no").click(function() {
promise.resolve(false)
})
FIDDLE: https://jsfiddle.net/0g76ce5s/
实际上,我更喜欢你的第一种方法,因为它更关注分离。
但是如果你想做 Promise 方法,你需要传递的是 resolve
函数而不是 Promise。
示例如下:
var resolveGlobal; // declare so that it's available both from within `add-item` and `button` handlers
$(".add-item").click(function () {
promise = new Promise(function (resolve, reject) {
var ask_about_flag = true;
if (ask_about_flag) {
$("#flag_modal").modal("show");
resolveGlobal = resolve;
} else {
resolve(null);
}
});
promise.then(function (flag) {
// flag is the parameter passed to resolve
addItem(flag);
});
});
$("#yes").click(function () {
resolveGlobal(true);
});
$("#no").click(function () {
resolveGlobal(false);
});
function addItem(flag) {
console.log(flag);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
<script
src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"
></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"
></script>
</head>
<body>
<div id="box">
<div
class="modal fade"
tabindex="-1"
role="dialog"
aria-labelledby="flag_modal"
aria-hidden="true"
id="flag_modal"
>
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title serif text-center">
Add with a flag?
</h2>
</div>
<div class="modal-body">
<!-- detailed instructions -->
<button id="yes" class="btn btn-lg">Yes</button>
<button id="no" class="btn btn-lg">No</button>
</div>
</div>
</div>
</div>
<button class="add-item">Add item</button>
</div>
</body>
</html>