我有一个用于创建新对象和编辑现有对象的表单。该表单包含一些插件(日期选择器,jstree),我正在尝试使用jquery延迟来使加载更干净。这是我第一次尝试使用延迟对象。
我想要做的是首先加载表单,然后如果我正在编辑现有表单,我还想用现有值填充表单。我的成本看起来像这样(它是coffeescript,但我认为它非常易读)
$.when(
# These functions all return jquery.Deferred objects.
getBookingDetails(id), buildJstree(), buildCalendar()
).then(
# Editing an existing booking
(bookingResponse, jstreeResponse_ignored, calendarResponse_ignored) =>
# ... populate form with data from bookingResponse ...
$("#name").val(bookingResponse[...])
# etc., Rest is omitted
).fail(
# Creating a new booking, so don't need to do anything more to the form.
() ->
)
因此,如果我正在编辑,我希望$ .when()能够解析并放入then()。如果我要创建一个新的预订,我会人为地导致$ .when()失败,就像这样
getBooking: (id) =>
if id is null
return $.Deferred().reject('id is null')
return $.ajax({
url : base + "/api/v1/daily/id/#{id}"
type : "GET"
contentType: "application/json"
data : {}
})
但是我觉得这是错误的,因为如果$ .when()中的任何其他延迟对象失败,例如因为我的插件没有正确加载,所以我需要做额外的工作来检查这个错误,这只是感觉不正确。
如果我的方法确实不好,你能解释一下为什么吗?
如何正确地重组事物?
答案 0 :(得分:0)
在考虑了这个之后,我想出了一个解决方案。我们的想法是将$.when()
分成两个主要组成部分:插件并加载以前的预订数据。首先,我构建了一个$.when()
构造来加载插件。
$.when( # load plugins
buildJstree(), buildCalendar()
).fail( # Handle failed plugins
() -> # Code to handle failed plugin.
)
现在,如果其中一个插件失败,那么执行将停止,我可以处理该失败的插件。
如果所有插件加载成功,那么我可以加载我的预订并继续,所以我有:
$.when( # Load plugins.
buildJstree(), buildCalendar()
).fail(
() -> # Code to handle failed plugin.
).then( # Load previous booking data.
() ->
# If it's a new booking, don't need to load previous data.
return if id is null
# Editing an existing booking
getBookingDetails(id)
.then(
(bookingResponse) =>
# ... populate form with data from bookingResponse ...
$("#name").val(bookingResponse[...])
# etc., Rest is omitted
)
)
所以现在我有了一个流水线方法,加载插件,然后加载数据,然后填充表单。
我也不需要拒绝Deferred对象作为我预期控制流的一部分,因为我提前检查了一个空字符串。事后看来,我原本可以在我的初始代码中完成此操作。