我正在使用RxJS来收听表单提交事件,并通过AJAX提交它(它是一个奇怪的代码,但我现在只是尝试使用RxJS,所以请耐心等待我)。我想要做的只是在请求不在进行时才允许提交。
到目前为止我的代码看起来像这样(并且是#34;工作"):
Rx.DOM.submit(formEl)
.map(function(event){ event.preventDefault(); return event; })
.map(function(){ return getEmailAddress(formEl); })
.subscribe(function(email){
submitToMailChimp(url, email).done(showMailChimpThanks(orbitInstance)).fail(showMailChimpError);
});
我的问题是我不确定如何实现适应这种限制的东西(看过skipUntil但不太确定在这种情况下如何处理)。所以我的问题是:我如何(a)阻止提交直到我的Ajax请求完成,以及(b)优化我的代码以在链的末尾发出Ajax请求,因此我可以subscribe
得到结果它,而不是这种奇怪的混合混合物。
最终解决方案:
var submissions = Rx.DOM.submit(formEl);
submissions.subscribe(preventDefaultEvent);
var requests = submissions
.first()
.map(getEmailAddress(formEl))
.flatMap(submitToMailChimp(url))
.catch(showMailChimpError(submitButton))
.repeat();
requests.subscribe(showMailChimpThanks(orbitInstance, submitButton));
答案 0 :(得分:3)
好问题。在first()
之后使用submit
仅允许一次提交,并在ajax请求完成后(我们将通过flatMap
调用),此观察结果将完成(因为first
)。因此,我们附加一个repeat()
,以便在第一个提交完成后开始侦听下一个提交。因为如果其中一个ajax调用失败,我想您不想停止流,我们会将您的ajax请求的结果转换为Error
或结果,并将此“Either”作为数据流式传输(见this question)
棘手的部分是,您还要确保每次即使在处理当前提交时我都会调用preventDefault
,而我们目前还没有收听submit
。在我看来,这是一个具有不同观察要求的不同动作,因此我们应该将其作为单独的查询来编写。因此我们最终得到:
var submissions = Rx.DOM.submit(formEl);
// send ajax requests on submissions
submissions
.first()
.flatMap(function (event) {
var email = getEmailAddress(formEl);
return submitToMailChimp(url, email)
.then(
function (v) { return v; },
function (e) { return new Error(e); });
})
.repeat()
.subscribe(function (result) {
if (result instanceof Error) {
showMailChimpError(result);
}
else {
showMailChimpThanks(instance);
}
});
// prevent defaults
submissions.subscribe(function (ev) { ev.preventDefault(); });