0

我有一个 DNN 模块,它将使用 Lightslider 构建产品轮播。

当页面加载时,从我们的 ERP 服务器数据库中获取 10 个产品需要几秒钟。在加载时,当我尝试导航到另一个页面时,它不会重定向,直到 Ajax 查询返回数据。它会等到产品加载完毕,然后它会重定向到我大约 5 秒前点击的链接。

我已启用 async: true 并尝试将异步添加到服务器端代码,但没有运气。

$(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 + "', 1, '" + 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 的服务器端,我尝试使用以下两种方式获取数据,但似乎没有区别。

没有异步代码的控制器代码(测试 1):

        /// <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;
            }
        }

带有异步代码的控制器代码(测试 2):

        /// <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.", ex.ToString(), 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.", ex.ToString(), 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,
            async: 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.", ex.ToString(), 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;
        }

企业资源计划代码

        ''' <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, ShowRRPOnly, 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, CustomerCode As String, ShowRRPOnly As Boolean, ProductCount 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, CustomerCode, 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, product.StockCode, GetCompanyIdFromDatabaseName(dao.dbName, 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, ISNULL(SP.FriendlyTitle, 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, ISNULL(SP.FriendlyTitle, FG.Description), FG.DetailedDescription, SP.SlugURL, ISNULL(SP.MetaTitle, ISNULL(SP.FriendlyTitle, FG.Description)), SP.MetaDescription, SP.MetaKeywords, SP.MainProductImageTitle, sp.MainProductImageDescription, FG.Price, fg.BarCode, 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
4

0 回答 0