0

我有一个 javascript 函数,其中每当有一个特定的select3 ajax Json 调用发生变化并sessionStorage填充 3 个用于创建动态下拉列表的项目。

// 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项目是否已设置的代码,似乎它们为空并且不进入if块。

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

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

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

4

1 回答 1

1

您可以使用 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 数据用于其他任何事情时)

于 2020-01-31T14:16:39.830 回答