JS 微调器仅在操作完成后显示

JS spinner only shows after action completes

这是一个我们一直在努力解决很长一段时间的问题。

该页面使用 fgnass 微调器。该页面建立在 angular 上。在执行任何类型的冗长 dom 操作时,我会尝试调用微调器,然后执行上述 dom 操作(例如,调用分页或在相当大的数据集上搜索)。这些操作可能需要几秒钟,因此需要微调器的原因是:让用户知道事情正在发生,并等待。

我尝试做的是。

function callSpinner()
{
    j$("div[class^='ui-dialog']").addClass('dialog_spinner');
    j$("div[class^='ui-dialog-buttonpane ui-widget-content']").css("display", "none");
    j$('#progressSpinner').dialog('open');
}
function closeSpinner()
{
    j$('#progressSpinner').dialog('close');
    j$("div[class^='ui-dialog']").removeClass('dialog_spinner');
}

这是使用 Michael Bromley 发现的 angular 分页库 here. 这发生在他的库的 scope.setCurrent 函数中。

scope.setCurrent = function(num) {
callSpinner();
paginationService.setCurrentPage(paginationId, num);
closeSpinner();
}

也就是说,标准 Angular 过滤器也会出现这种情况。

这是创建页面时调用的 createSpinner 方法(我还在页面加载时启动微调器一次)

function CreateSpinner()
{
    // initialize spinner.
var opts = {
    lines: 13, // The number of lines to draw
    length: 15, // The length of each line
    width: 5, // The line thickness
    radius: 15, // The radius of the inner circle
    corners: 1, // Corner roundness (0..1)
    rotate: 0, // The rotation offset
    direction: 1, // 1: clockwise, -1: counterclockwise
    color: '#E68A2E', // #rgb or #rrggbb or array of colors
    speed: 1, // Rounds per second
    trail: 60, // Afterglow percentage
    shadow: false, // Whether to render a shadow
    hwaccel: false, // Whether to use hardware acceleration
    className: 'spinner', // The CSS class to assign to the spinner
    zIndex: 2e9, // The z-index (defaults to 2000000000)
    top: '50', // Top position relative to parent in px
    left: '30' // Left position relative to parent in px
};
var target = document.getElementById('progressSpinner');
$spinner = new Spinner(opts).spin(target);
j$("div[class='ui-widget-overlay ui-front']").addClass('overlay_style1');
}

这是我定位的微调标签的 HTML。

<div id="progressSpinner" title="Progress" style="display: none; background-color: #000000; z-index: 1200; opacity: 0.8; padding: 0;"></div>

但实际上发生了什么,它是否触发了分页操作,并等待调用微调器直到分页过程完成。所以页面什么都不做,分页完成,表单更新,然后微调器启动,然后关闭。

正如我所说,我在页面加载时创建微调器,然后在页面准备好时调用 callSpinner 函数。效果不错。

我可以随时调用 callSpinner,它也很好用。

我什至可以在控制台打开旋转器,然后触发分页点击,旋转器一直旋转。

经过各种尝试做不同的事情后,我终于让它工作了。在任何时候,我的代码都没有任何特别的错误。如果我在

的每个代码行放置调试中断
callSpinner();
paginationService.setCurrentPage(paginationId, num);
closeSpinner();

一切正常。

我终于弄清楚发生了什么是浏览器一次获取所有 3 行代码。它决定 运行 setCurrentPage 函数比其他任何东西都重要。所以它对整个事情进行分页,然后它会 运行 callSpinner();然后它立即 运行s 关闭微调器。

我的解决方案:

callSpinner();
setTimeout(function () {
    scope.$evalAsync(
        function( scope ) {
            paginationService.setCurrentPage(paginationId, num);
            closeSpinner();
        }
    );
}. 200);

推理:据我所知,通过短暂延迟将分页调用置于超时状态,可以确保 callSpinner();在做任何事情之前执行。

本来我只是有timeout,但是timeout里的代码一调用,就会触发closeSpinner();先行,然后进行分页调用。所以我在其上使用了 Angular 的 $evalAsync,这让一切顺利进行。