Javascript SessionStorage 项目在第一个函数调用中不可用

标签 javascript html asp.net

我有一个 javascript 函数,每当特定 select 发生更改时,就会进行 3 个 ajax Json 调用,并填充 3 个 sessionStorage 项,这些项用于创建动态下拉菜单。

// Update PayScales, Designations and Fields based on change in Organisation dropdown
        $(document).on('change', '#EmployeeDetails_OrganisationId', function () { getOrgDependentFields($(this).children(":selected").val(), true) });


// Fetch PayScales, Designations and Fields based on Organisation
function getOrgDependentFields(orgID, reformatTable) {
            if (sessionStorage.promotionCount && reformatTable) {
                    $('#promotionTable tbody').html("");
                    sessionStorage.removeItem('promotionCount');
                }
            if (orgID != "") {
                var url = '@Url.Action("GetOrganisationDependentInfo", "EmployeeData")?organisationId=' + orgID;
                $.getJSON(
                    url + '&infoType=level', function (data) {
                        sessionStorage.setItem('levelJSON', JSON.stringify(data));
                    }
                );
                $.getJSON(
                    url + '&infoType=payscale', function (data) {
                        sessionStorage.setItem('payscaleJSON', JSON.stringify(data));
                    }
                );
                $.getJSON(
                    url + '&infoType=designation', function (data) {
                        sessionStorage.setItem('designationJSON', JSON.stringify(data));
                    }
                );

            } else {
                sessionStorage.removeItem("levelJSON");
                sessionStorage.removeItem("payscaleJSON");
                sessionStorage.removeItem("designationJSON");
            }
        }

现在,此select 输入已在页面加载时预先填充并具有特定值。

我还有一个按钮可以动态地将行添加到表中。单击此按钮时,将调用另一个方法,该方法检查这些 sessionStorage 项是否已设置/可用于生成表所需的动态 HTML。如果不是,它会调用 getOrgDependentFields 函数并尝试设置它们,然后再使用它们创建动态 html 行并将其附加到表

//Add new row to Promotion table
        $("#addPromotion").click(function () {
            if (sessionStorage.promotionCount) {
                sessionStorage.promotionCount = Number(sessionStorage.promotionCount) + 1;
            } else {
                sessionStorage.promotionCount = @((Model.PromotionDetails == null) ? 0 : Model.PromotionDetails.Count());
            }
            var newPromotion = sessionStorage.promotionCount;
            var designationNames = '<option selected="selected" value="">Select Designation</option>';
            var levelNames = '<option selected="selected" value="">Select Level</option>';
            var payScaleNames = '<option selected="selected" value="">Select PayScale</option>';


          //Check if sessionStorage items are set and attempt to set them if NOT
           if (null == sessionStorage.getItem("designationJSON")) 
           {
         getOrgDependentFields($("#EmployeeDetails_OrganisationId").children(":selected").val(), false);

            }

            // Use the set sessionStorage items if they are set
            if (null != sessionStorage.getItem("designationJSON") && null != sessionStorage.getItem("levelJSON") && null != sessionStorage.getItem("payscaleJSON")) // Use the sessionStorage items if set 
            {
                var designationJSON = JSON.parse(sessionStorage.getItem("designationJSON"));
                designationJSON.forEach(function (designation) { designationNames += '<option value="' + designation.Id + '">' + designation.Name + '</option>'; });

                var levelJSON = JSON.parse(sessionStorage.getItem("levelJSON"));
                levelJSON.forEach(function (level) { levelNames += '<option value="' + level.Id + '">' + level.Name + '</option>'; });

                var payscaleJSON = JSON.parse(sessionStorage.getItem("payscaleJSON"));
                payscaleJSON.forEach(function (payscale) { payScaleNames += '<option value="' + payscale.Id + '">' + payscale.Name + '</option>'; });
            }
            // Bunch of other stuff to be done
        });

我面临的问题是,当我第一次单击按钮时,会调用 on click 方法,并且它会调用代码部分来调用函数 getOrgDependentFields (我已在调试器中检查过) 并成功遍历它,但是当它遇到检查这些 sessionStorage 项是否已设置的代码时,它会将它们视为 null,并且不会进入 if block 。

但是,在下次单击该按钮时,当它检查是否设置了 sessionStorage 项时,它能够成功地看到它们,并且代码正常进行并进入下一个 if block 。

显然,sessionStorage 项在第一个事件执行完成后设置/可用

造成这种延迟的可能原因是什么?

最佳答案

您可以使用 jQuery.when 来了解所有请求何时完成。 将依赖于请求的代码移至另一个函数,并在事件处理程序中检查请求是否已完成。

如果数据存在,则运行立即呈现行的函数,如果不存在,则运行请求,然后运行呈现行的函数。

// Fetch PayScales, Designations and Fields based on Organisation
function getOrgDependentFields(orgID, reformatTable) {
    if (sessionStorage.promotionCount && reformatTable) {
        $('#promotionTable tbody').html("");
        sessionStorage.removeItem('promotionCount');
    }

    if (orgID != "") {
        var url = '@Url.Action("GetOrganisationDependentInfo", "EmployeeData")?organisationId=' + orgID;
        var request1 = $.getJSON(
            url + '&infoType=level', function (data) {
                sessionStorage.setItem('levelJSON', JSON.stringify(data));
            }
        );
        var request2 = $.getJSON(
            url + '&infoType=payscale', function (data) {
                sessionStorage.setItem('payscaleJSON', JSON.stringify(data));
            }
        );
        var request3 = $.getJSON(
            url + '&infoType=designation', function (data) {
                sessionStorage.setItem('designationJSON', JSON.stringify(data));
            }
        );

        return $.when(request1, request2, request3);
    } else {
        sessionStorage.removeItem("levelJSON");
        sessionStorage.removeItem("payscaleJSON");
        sessionStorage.removeItem("designationJSON");

        return $.Deferred().resolve();
    }
}

$("#addPromotion").click(function () {
  //Check if sessionStorage items are set and attempt to set them if NOT
  var dataExists = null != sessionStorage.getItem("designationJSON") &&
                      null != sessionStorage.getItem("levelJSON")
                      && null != sessionStorage.getItem("payscaleJSON");

    if (dataExists)
    {
        render();
    } else
    {
        getOrgDependentFields(
            $("#EmployeeDetails_OrganisationId").children(":selected").val(), false
        ).then(render);
    }
});

function render() {
    if (sessionStorage.promotionCount) {
        sessionStorage.promotionCount = Number(sessionStorage.promotionCount) + 1;
    } else {
        sessionStorage.promotionCount = @((Model.PromotionDetails == null) ? 0 : Model.PromotionDetails.Count());
    }

    var newPromotion = sessionStorage.promotionCount;
    var designationNames = '<option selected="selected" value="">Select Designation</option>';
    var levelNames = '<option selected="selected" value="">Select Level</option>';
    var payScaleNames = '<option selected="selected" value="">Select PayScale</option>';

    var designationJSON = JSON.parse(sessionStorage.getItem("designationJSON"));
    designationJSON.forEach(function (designation) { designationNames += '<option value="' + designation.Id + '">' + designation.Name + '</option>'; });

    var levelJSON = JSON.parse(sessionStorage.getItem("levelJSON"));
    levelJSON.forEach(function (level) { levelNames += '<option value="' + level.Id + '">' + level.Name + '</option>'; });

    var payscaleJSON = JSON.parse(sessionStorage.getItem("payscaleJSON"));
    payscaleJSON.forEach(function (payscale) { payScaleNames += '<option value="' + payscale.Id + '">' + payscale.Name + '</option>'; });

    // Bunch of other stuff to be done
}

如果直接使用请求中的 json(仅当您不需要 sessionStorage 数据进行其他任何操作时),代码可以进一步简化

关于Javascript SessionStorage 项目在第一个函数调用中不可用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59985629/

相关文章:

javascript - Ruby/Sinatra/jQuery 应用程序未在 repl.it 中运行

javascript - 在 AngularJS 中,ui-view 加载的内容无法读取父内容中的 javascript 文件

javascript - 在 iframe 内提交字段

html - 编织 HTML - 从错误中恢复?

c# - 在 gridview 行命令中获取 BoundField 值

c# - MVC4 共享模板

javascript - Django 中的 URL 检测和缩短

javascript - 创建 JavaScript 自定义事件

c# - 获取具有给定列标题的列的索引 C#

javascript - API 嵌入代码正在发送 &lt;style&gt;,我该如何忽略?