我正在構建一個需要列出產品類別和子類別的應用程序。這是使用Deferred對象的正確方法嗎?
當用戶選擇一個類別時,與該類別相關的子類別將從服務器加載ajax,但前提是它們以後未加載(在這種情況下,它們是從DOM加載的)。
代碼:http://jsbin.com/abijad/edit#javascript,html
var $form = $('#new-product-form');
$form.on('change', 'select.product-categories', function(e) { //I'm using event delegation for a future feature...
getSubCategories($(this).val()).done(function($subCategoriesEl){
$form.find('select.product-subcategories').not($subCategoriesEl).hide();
$subCategoriesEl.show();
});
});
var getSubCategories = function(categoryId) {
var dfd = $.Deferred(),
$alreadyisLoaded = $form.find('select.product-subcategories').map(function(idx, el){
if(parseInt($(this).data('category'), 10) === parseInt(categoryId, 10)){
return el;
}
});
if($alreadyisLoaded.length > 0){ //don't request subCategories that already are loaded
console.log('SubCategory loaded from DOM');
dfd.resolve($alreadyisLoaded);
} else {
var subCategoriesHtml = '<select data-category="' + categoryId + '" class="product-subcategories">';
$.get('/', { //The ajax request will only be simulated
categoryId : categoryId
}, function (result) {
//simulate success :X
result = {"status":1,"data":[{"name":"Sub-Category I","id":1},{"name":"Sub-Category II","id":2},{"name":"Sub-Category III","id":3}]};
console.log('SubCategory loaded with Ajax');
if(result.status === 1) { //Success
for(var subCategoryInfo in result.data) {
if(result.data.hasOwnProperty(subCategoryInfo)){
subCategoriesHtml += '<option value="' + result.data[subCategoryInfo].id + '">';
subCategoriesHtml += result.data[subCategoryInfo].name + '</option>';
}
}
subCategoriesHtml += '</select>';
var $subCategories = $(subCategoriesHtml).hide().appendTo($form);
dfd.resolve($subCategories);
} else {
dfd.reject();
}
});
}
return dfd.promise();
};
<form id="new-product-form">
<select class="product-categories">
<option value="1">Category I</option>
<option value="2">Category II</option>
<option value="3">Category III</option>
<option value="4">Category IV</option>
<option value="5">Category V</option>
</select>
<select data-category="1" class="product-subcategories">
<option value="1">SubCategory I</option>
<option value="2">SubCategory II</option>
<option value="3">SubCategory III</option>
<option value="4">SubCategory IV</option>
<option value="5">SubCategory V</option>
</select>
</form>
因爲代碼快滿了回調這裏和那裏,我決定使用jQuery的Deferred對象,但我不知道這是否是正確的實施。有人可以告訴我,我做了正確的事情,還是應該做不同的事情?
除了鏈接之外,請在問題中包含相關代碼。目標是儘可能保持SO自足。如果外部網站消失,問題仍然應該是相關的。 – 2012-01-31 01:41:49
@JamesMontagne請參閱編輯。 – JCM 2012-01-31 01:55:38
我只會緩存延遲對象,並重新構建每個後續更改的選項,以避免最終在非常大的類別/子類別情況下有大量隱藏的元素,但除此之外,您擁有的將作爲只要元素的數量不會太大。 – 2012-01-31 01:57:52