如何解决无法让 JQuery Ajax 在 DNN 上真正异步运行,如果你点击一个链接,它会等待服务器先带回数据然后重定向
我有一个 DNN 模块,可以使用 Lightslider 构建产品轮播。
当页面加载时,从我们的 ERP 服务器数据库中获取 10 个产品需要几秒钟的时间。 在加载时,当我尝试导航到另一个页面时,它不会重定向,直到 Ajax 查询返回数据。它将等到产品加载完毕,然后重定向到我大约 5 秒前点击的链接。
我已启用 async: true 并尝试将 async 添加到服务器端代码,但没有成功。
$(document).ready(function () {
GetCarouselProductData();
});
async function GetCarouselProductData() {
var CarouselModID = "<%=CarouselModID%>";
var CarouselMode = "<%=CarouselMode%>";
var CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetRandomCarouselProductssqlAsync?ModID=' + CarouselModID;
if (CarouselMode == 'SpecificSKU') {
CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetSpecificSKUCarouselProductsAsync?ModID=' + CarouselModID;
}
await $.ajax({
type: "GET",contentType: "application/json; charset=utf-8",cache: false,url: CarouselURL,datatype: "json",async: true,success: function (data) {
var counter = 0;
var VatText = "<%=IncTaxText%>";
var DetailedLinkRedirect = "<%=DetailedPageLink%>/sku/";
if (data.length > 0) {
var source = "";
$.map(data,function (item) {
var ImageSRC;
if (item.Productimages.length > 0) {
ImageSRC = item.Productimages[0].ProductThumbUrl
} else {
ImageSRC = '/DesktopModules/RandomProductCarousel/Images/no_image.png';
}
var alphabet = (counter + 10).toString(36);
var TitleDescription = item.Title;
if (TitleDescription.length > 70) {
var NewTitle = TitleDescription.substr(0,70);
NewTitle = NewTitle.substr(0,NewTitle.lastIndexOf(" ")) + '...';
} else {
var NewTitle = TitleDescription;
}
var StockCode = item.StockCode.trim();
var FinalRedirectLink = DetailedLinkRedirect + StockCode;
source += "<li class=\"item-" + alphabet +"\">"+
"<div class='Box'>"+
"<!--image Box-------->"+
"<div class='slide-img'>"+
"<img src='" + ImageSRC + "' alt='" + item.Title + "' />"+
"<!--overlay-->"+
"<div class='overlay-carousel'>"+
"<!--buy btn---->" +
"<div class='overlay-inner-carousel-btn-positioning'><a href='javascript:void(0);' class='carousel-quote-btn' onclick=\"addQuoteWithOnClickFunction('" + item.StockCode + "',1,'" + item.CustomerPriceInclVat + "');\">Add to Quotes</a></div>" +
"<div class='overlay-inner-carousel-btn-positioning'><a href='javascript:void(0);' class='carousel-buy-btn' onclick=\"addProductWithOnClickFunction('" + item.StockCode + "','" + item.CustomerPriceInclVat + "');\"><%=CartButtonText%> </a></div>" +
"<div class='overlay-inner-carousel-btn-positioning'>" +
"<a href='" + FinalRedirectLink + "' class='carousel-view-btn'>View</a>" +
"</div>" +
"</div>"+
"</div>"+
"<!--Detail Box-->"+
"<div class='detail-Box'>"+
"<!--type-->"+
"<div class='type'>"+
"<a href='" + DetailedLinkRedirect + item.StockCode + "'>" + NewTitle +"</a>"+
"</div>"+
"<!--price-->" +
"<div class='CarouselStockCode'>" +
"<span class='carousel-stock'>" + StockCode + "</span>" +
"</div>" +
"<span class='price'>" + item.CustomerPriceInclVat + " " + VatText + "</span>" +
"</div>"+
"</div>"+
"</li>";
counter++;
return source;
});
$("#autoWidth2").remove();
$(".lSSlideOuter").remove();
$(".responsive-product-carousel").remove();
$(".responsive-product-carousel2").append(source);
}
},error: function (xhr,ajaxOptions,thrownError) {
$.fancybox.open(xhr.responseText);
}
}).promise().done(function () {
$(document).ready(function () {
//ZR - 29/01/2021 - Mode that determines if it should auto slide
var SliderMode = "<%=AutoSlideSetting%>";
if (SliderMode == "False") {
SliderMode = false;
} else {
SliderMode = true;
}
//ZR - 29/01/2021 - Sets the loop mode of the slider
var LoopMode = "<%=LoopSliderSetting%>";
if (LoopMode == "False") {
LoopMode = false;
} else {
LoopMode = true;
}
var SliderPauseTime = <%=SliderPausePeriod%>;
// website for settings sachinchoolur.github.io/lightslider/settings.html
$('#autoWidth').lightSlider({
autoWidth: true,loop: LoopMode,adaptiveHeight: true,pauSEOnHover: true,auto: SliderMode,pause: SliderPauseTime,onSliderLoad: function () {
$('#autoWidth').removeClass('cS-hidden');
}
});
ViewCarouselProductLoading();
});
});
在Controller的服务器端,我尝试使用以下两种方式来获取数据,但似乎没什么区别。
/// <summary>
/// Get Random Product information via sql
/// </summary>
/// <returns></returns>
/// <remarks>ZR 25/01/2021</remarks>
[AllowAnonymous]
[HttpGet]
public object GetRandomCarouselProductssqlAsync(int ModID)
{
try
{
AmountOfRandomProductsToFetch = TryGetPortalSetting("AmountOfRandomProductsToLoad_" + ModID);
return GetRandomProductsFromsql(Int32.Parse(AmountOfRandomProductsToFetch));
}
catch (Exception ex)
{
EventLogController logController = new EventLogController();
logController.AddLog("Could not retreive random products for the Product Carousel via sql.",ex.ToString(),EventLogController.EventLogType.ADMIN_ALERT);
throw;
}
}
/// <summary>
/// Get Random Product information via sql
/// </summary>
/// <returns></returns>
/// <remarks>ZR 25/01/2021</remarks>
[AllowAnonymous]
[HttpGet]
public async System.Threading.Tasks.Task<object> GetRandomCarouselProductssqlAsync(int ModID)
{
try
{
return await GetRandomProductssqlAsync(ModID);
}
catch (Exception ex)
{
EventLogController logController = new EventLogController();
logController.AddLog("Could not retreive random products for the Product Carousel via sql.",EventLogController.EventLogType.ADMIN_ALERT);
throw;
}
}
public async System.Threading.Tasks.Task<object> GetRandomProductssqlAsync(int ModID)
{
try
{
AmountOfRandomProductsToFetch = TryGetPortalSetting("AmountOfRandomProductsToLoad_" + ModID);
return GetRandomProductsFromsql(Int32.Parse(AmountOfRandomProductsToFetch));
}
catch (Exception ex)
{
EventLogController logController = new EventLogController();
logController.AddLog("Could not retreive random products for the Product Carousel via sql.",EventLogController.EventLogType.ADMIN_ALERT);
throw;
}
}
我什至尝试使用“Then”以不同方式执行 Ajax 调用,但没有成功。
$(window).load(function () {
console.log("window is loaded");
doAjaxGet()
.then(json => {
console.log('json: ',json);
processjsONData(json);
})
});
async function doAjaxGet() {
var CarouselModID = "<%=CarouselModID%>";
var CarouselMode = "<%=CarouselMode%>";
var CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetRandomCarouselProductssqlAsync?ModID=' + CarouselModID;
if (CarouselMode == 'SpecificSKU') {
CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/PRandomProductCarousel/API/RandomProductCarousel/GetSpecificSKUCarouselProductsAsync?ModID=' + CarouselModID;
}
const result = await $.ajax({
url: CarouselURL,crossDomain: true,type: 'GET',});
return result;
}
function processjsONData(data) {
// NOTE: data is already parsed
$.map(data,function (item) {
console.log('Data: ',item.Title);
});
}
更新
我已将前端代码更改为使用普通的 XMLHttpRequest 而不是 JQuery Ajax。我在下面有两个视频来展示它到底在做什么以及下面的 Javascript Ajax 代码。
视频 1(构建产品轮播)
https://www.youtube.com/watch?v=n637FGv3e9U
视频 2(仅将产品标题记录到控制台日志)
https://www.youtube.com/watch?v=8mHNcgBoe-Q
Javascript Ajax 代码:
$(document).ready(function () {
JavascriptCarouselFetch();
});
function JavascriptCarouselFetch() {
var CarouselModID = "<%=CarouselModID%>";
var CarouselURL = $.fn.GetBaseURL() + 'DesktopModules/ParrotRandomProductCarousel/API/RandomProductCarousel/GetRandomCarouselProductssqlAsync?ModID=' + CarouselModID;
var http = new XMLHttpRequest();
http.open("GET",CarouselURL,true);
http.send();
http.onreadystatechange = function () {
if (http.readyState == 4 && http.status == 200) {
$.map(JSON.parse(http.response),function (item) {
console.log("Data: " + item.Title);
})
}
};
控制器代码:
/// <summary>
/// Get Random Product information via sql
/// </summary>
/// <returns></returns>
/// <remarks>ZR 25/01/2021</remarks>
[AllowAnonymous]
[HttpGet]
public async System.Threading.Tasks.Task<object> GetRandomCarouselProductssqlAsync(int ModID)
{
try
{
AmountOfRandomProductsToFetch = TryGetPortalSetting("AmountOfRandomProductsToLoad_" + ModID);
return GetRandomProductsFromsql(Int32.Parse(AmountOfRandomProductsToFetch));
}
catch (Exception ex)
{
EventLogController logController = new EventLogController();
logController.AddLog("Could not retreive random products for the Product Carousel via sql.",EventLogController.EventLogType.ADMIN_ALERT);
throw;
}
}
/// <summary>
/// Gets Random Products from sql
/// </summary>
/// <param name="ProdCode"></param>
/// ZR 25/01/2021</remarks>
public object GetRandomProductsFromsql(int AmountOfRandomProductsToFetch)
{
try
{
if (AmountOfRandomProductsToFetch > 0)
{
int pid = PortalController.Instance.GetCurrentPortalSettings().PortalId;
if (SessionManager.GSettings == null) SessionManager.GSettings = new ParrotDNNCommon.Components.GlobalSettings(pid);
var portalCtrl = new ParrotDNNCommon.Controllers.ParrotPortalSettingsController();
var parrotPortalController = new ParrotPortalSettingsController();
var currSettings = parrotPortalController.GetPortalSettings(pid);
return m_Product.GetRandomProductWebDetailsFromsql(SessionManager.GSettings.Globalvars,pid,AmountOfRandomProductsToFetch,currSettings.PricingModeIsShowRRPOnly);
}
return null;
}
catch (Exception exc)
{
throw;
}
}
公共类
/// <summary>
/// Get the product details
/// </summary>
/// <param name="GV">Global Variables</param>
/// <param name="WebPortalId">Web Portal ID</param>
/// <param name="Count">Amount of random products to return</param>
/// <param name="ShowRRPOnly">Boolean to determine if RRP should only show or not</param>
/// <returns>WebProductDetails</returns>
/// <remarks>ZR - 25/01/2021</remarks>
public List<CommonDataDeFinitions.Products.WebProductDetails> GetRandomProductWebDetailsFromsql(CommonLibrary.Globalvars GV,int WebPortalId,int Count,bool ShowRRPOnly)
{
List<CommonDataDeFinitions.Products.WebProductDetails> result = new List<CommonDataDeFinitions.Products.WebProductDetails>();
try
{
result = GV.ClHelper.eBusiness.GetRandomProductWebDetails(WebPortalId,SessionManager.CurrentUserInfo.CustomerCode,ShowRRPOnly,Count,SessionManager.CurrentUserInfo.ParrotUserId);
}
catch (Exception ex)
{
EventLog.LogEvent("GetProductWebDetails","There was an error retrieving the product details. " + ex.Message,DotNetNuke.Services.Log.EventLog.EventLogController.EventLogType.ADMIN_ALERT);
}
return result;
}
ERP 代码
''' <summary>
''' Gets a Random Collection of <see cref="WebProductDetails"/> and pricing for the website.
''' </summary>
''' <param name="WebPortalId"><see cref="Integer"/>: Target Web Portal Id.</param>
''' <param name="CustomerCode"><see cref="String"/>: Customer Code.</param>
''' <param name="ShowRRPOnly"><see cref="Boolean"/>: Show RRP Only.</param>
''' <param name="ProductCount"><see cref="Integer"/>: Count of Products to Return.</param>
''' <param name="WebUserId"><see cref="Integer"/>: Web User Id.</param>
''' <returns><see cref="List(Of WebProductDetails)"/></returns>
''' <remarks>KeS/ZR 25/01/2021: created.</remarks>
Friend Function GetRandomProductWebDetails(WebPortalId As Integer,CustomerCode As String,ShowRRPOnly As Boolean,ProductCount As Integer,WebUserId As Integer) As List(Of WebProductDetails)
Dim Result As List(Of WebProductDetails) = GetRandomProductDetailsForWeb(WebPortalId,CustomerCode,ProductCount,WebUserId)
Return Result
End Function
''' <summary>
''' Gets a Random Collection of <see cref="WebProductDetails"/> and pricing for the website.
''' </summary>
''' <param name="WebPortalId"><see cref="Integer"/>: Target Web Portal Id.</param>
''' <param name="CustomerCode"><see cref="String"/>: Customer Code.</param>
''' <param name="ShowRRPOnly"><see cref="Boolean"/>: Show RRP Only.</param>
''' <param name="ProductCount"><see cref="Integer"/>: Count of Products to Return.</param>
''' <param name="WebUserId"><see cref="Integer"/>: Web User Id.</param>
''' <returns><see cref="List(Of WebProductDetails)"/></returns>
''' <remarks>KeS/ZR 25/01/2021: created.</remarks>
Friend Function GetRandomProductDetailsForWeb(WebPortalId As Integer,WebUserId As Integer) As List(Of WebProductDetails)
Dim result As List(Of WebProductDetails) = New List(Of WebProductDetails)
Try
result = dao.FinishedGoods.GetRandomWebProductDetailsByCount(ProductCount)
If result.IsNullOrEmpty() Then Return New List(Of WebProductDetails)
'User Id < 0 is not logged in,recommended price will always be fetched
Dim canWebUserViewCustomerPrice As Boolean = If(WebUserId <= 0,True,CheckIfUserHasWebRight(UserRights.WebUserCanViewStockItemPrices,WebUserId))
'override the User Right if DNN site set to always show recommended price no matter what
If (ShowRRPOnly) Then canWebUserViewCustomerPrice = False
For Each product In result
'Get the customer pricing,DS 21/06/2017 - fixed to get correct Web channel default ID,Now uses default obj for this
Dim priceCalc As StockItemPricingForCustomer = blHelper.Fingoods.GetStockItemPricingForCustomer(DefaultStockItemPricingForwebargs(product.StockCode,Not canWebUserViewCustomerPrice,dao.Customers.SelectCustomerDealerType(CustomerCode)))
'RB 2017-07-11: Get the Kit Items for the product
Dim CodeList As IList(Of String)
CodeList = New List(Of String)
CodeList.Add(product.StockCode)
Dim relatedProducts As List(Of RelatedProduct) = dao.DaoPortal.SelectKitItems(CodeList)
product.KitItems = relatedProducts
product.ShowStockAvailable = blHelper.SystemRules.WebShowStockAvailability()
product.NoStockAvailableMessage = blHelper.SystemRules.WebNoStockAvailableMessage()
product.RetailPriceExVat = priceCalc.RetailPrice
product.Customerdiscount = priceCalc.Customerdiscount
product.CustomerPriceExVat = priceCalc.CustomerPrice
product.CustomerPriceInclVat = priceCalc.PriceWithTax
product.ExtraInfo = dao.FinishedGoods.SelectDetailedDescriptionForStockCode(product.StockCode).DescriptionHTML
product.DownloadLinksHTML = blHelper.Fingoods.GenerateProductDownloadLinksHTML(String.Empty,product.StockCode,"line-height:20px;text-align:left;",GetCompanyIdFromDatabaseName(dao.dbname,WebPortalId))
product.Productimages = blHelper.Fingoods.GetProdcutimageLinksOnly(String.Empty,WebPortalId))
' RB 2017-10-11: Lifestyle data for the product StockParent_MetaData
Dim MetaData As StockParent_MetaData = dao.Productvariations.SelectMetaData(product.StockID)
product.ShowWebInfoButton = MetaData.ShowAdditionalWebInfo
product.WebInfoURL = MetaData.AdditionalWebInfoURL
product.WebInfoTarget = MetaData.AdditionalWebInfoTargetdisplay
product.WebInfoButtonText = MetaData.AdditionalWebInfoButtonText
' Rest of MetaData can also be returned here
'DS 21/01/2019 - Fetch Individual Warehouse Stock Levels and set the new property (following the business rule for showing stock)
If product.ShowStockAvailable Then product.WarehouseStockLevels = LLDataUtils.ConvertDataTabletoObjectListUsingIMapFromDataTableInterface(Of PortalWarehouseStockLevel)(dao.DaoPortal.SelectWarehouseStockLevelsForPortal(New String() {product.StockCode},nothing))
product.ItemsInStock = If(product.ShowStockAvailable,product.WarehouseStockLevels.Sum(Function(w) w.Amount),-1)
Next
Catch ex As Exception
CommonServer.ErrorHandler.ServerError(ex,"An error occurred attempting to retrieve a Random Assortment of Products for the Website",ExceptionTypes.UndefinedException,True)
End Try
Return result
End Function
''' <summary>
''' Get Random product details for the web for the provided count of items.
''' </summary>
''' <returns>WebProductDetails</returns>
''' <remarks>KeS/ZR 25/01/2021: created.</remarks>
Friend Function GetRandomWebProductDetailsByCount(Count As Integer) As List(Of WebProductDetails)
Dim sql As New StringBuilder
With sql
.AppendLine($" SELECT TOP {Count} SP.Id 'StockID',SP.StockCode 'StockCode',ISNULL(SP.FriendlyTitle,FG.Description) 'Title','' as 'Description',FG.DetailedDescription 'ExtraInfo',")
.AppendLine(" SP.SlugURL 'SlugURL',ISNULL(SP.MetaTitle,FG.Description)) 'MetaTitle',SP.MetaDescription 'MetaDesc',SP.MetaKeywords 'MetaKeywords',SP.MainProductimageTitle 'MainImageTitle',sp.MainProductimageDescription 'MainImageDesc',fg.BarCode,fg.PrimaryPublishingCategories_ID AS PrimaryPublishingCategoryID,")
.AppendLine(" FG.Price 'RetailPriceExVat',COUNT(ISNULL(W.QUANTITY,0)) 'ItemsInStock',PC.Name AS PrimaryPublishingCategoryName ")
.AppendLine(" FROM StockParent SP ")
.AppendLine(" INNER JOIN Fingoods FG ON FG.Id = SP.Id AND FG.IsDeleted = 0 AND FG.Publish = 1")
.AppendLine(" LEFT JOIN WAREHOUSESTOCK W ON w.FinGoods_ID = SP.Id ")
.AppendLine(" LEFT JOIN PublishingCategories AS PC ON PC.ID = FG.PrimaryPublishingCategories_ID AND PC.IsDeleted = 0 ")
.AppendLine(" WHERE SP.IsDeleted = 0 ")
.AppendLine(" GROUP BY SP.Id,SP.StockCode,FG.Description),FG.DetailedDescription,SP.SlugURL,FG.Description)),SP.MetaDescription,SP.MetaKeywords,SP.MainProductimageTitle,sp.MainProductimageDescription,FG.Price,fg.PrimaryPublishingCategories_ID,PC.Name")
.AppendLine(" ORDER BY NEWID() ")
End With
Using cmd As sqlCommandHelper = GetCommand(sql.ToString)
Return cmd.ExecuteList(Of WebProductDetails)
End Using
End Function
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。