繁体   English   中英

如何在执行过程中制作角度刷新屏幕

[英]How to make angular refresh screen in the middle of execution

我在三分之一的页面中有一点角html。

一切正常,代码正常,指令正常(“ ng-show”除外,该方法永远无效,但是在此无关紧要)。

但是我有一个繁重的代码,可以在按钮单击(使用ng-click )中运行。 在执行过程中,所有内容都会冻结,这是可以预期的。

但是我非常希望在执行过程中出现一个“ img”,但是似乎在代码执行过程中没有任何更新(在代码执行之后,所有内容都完美地更新了,但是代码执行期间却没有更新)。

在“ ng-click”中执行代码期间,如何“刷新”角度html?

我已经尝试过“ $ scope.apply()”和“ $ scope.digest()”,但是两者都会在控制台中引起一些奇怪的错误。


编辑

由于以下答案:错误确实是因为“应用/摘要”已在进行中。 通过使用所示的异步方法,我可以毫无问题地使用“应用”。

在图像上进行ng-show怎么样? 您可以使用一个div来占据要显示图像的整个部分,

<div ng-show="loading" class="some-class-to-display-image"></div> 

然后在您的js $scope.loading = true; 在处理/拨打电话等过程中,可以使用promise并在请求中使用.finally()并设置$scope.loading = false; 停止动画。

除非您遇到“ $ digest已经进行中”错误,因为您一次只能运行一个摘要循环,否则应该在$ scope.apply()中包装要首先执行的代码。

如果是这种情况,您可以尝试在$ timeout或$ evalAsync(Angular v1.2.x及以上)中显示加载图像后包装要执行的代码,以确保2个摘要周期不会冲突,即

    $scope.$apply(function () {
        //display loading image code
    });
    //Other code

要么

    //display loading image code
    $scope.$evalAsync(function () {
        //Other code
    });

JavaScript在浏览器环境中的工作方式是执行一块JavaScript直到完成为止,无论您使用AngularJS还是普通JavaScript,浏览器都不会呈现中间结果。

假设您对10.000个数据条目进行了繁重的操作,并希望显示进度条:

startButton.onclick = function onStartClick() {
  var progressbar = document.getElementById('progressbar');
  progressbar.style.width = "0";

  // process 100000 entries, update progress bar between
  for (var n = 0; n < 100000; y++) {
    doSomethingWithEntryNumber(n);
    progressbar.style.width = (n / 100000) + "%";
  }
}

它不会按预期更新浏览器中的progressbar div ,但会冻结浏览器,直到onDivClick完成。 这对于AngularJS来说没有什么不同,在AngularJS中处理大量数据不会更新您的UI。

要处理大量数据,您需要拆分工作并使用任何类型的“未来” /“承诺” /“延迟”技术-对于此示例:

startButton.onclick = function onStartClick() {
  var progressbar = document.getElementById('progressbar');
  progressbar.style.width = "0";

  // process 100000 entries in 1000 entry batches, update progress bar between
  function processBatch(batch) {
    for (var i = 0; i < 1000; i++) {
      doSomethingWithEntryNumber(batch*1000 + i);
    }
    // update progressbar
    progressbar.style.width = (batch / 1000) + "%";
    if (batch < 99) {
      // continue work after browser has updated UI
      setTimeout(processBatch.bind(this, batch + 1), 10);
    }
  }
  processBatch(0);
}

这样,浏览器可以呈现UI更改,用户可以滚动等,同时您仍然可以处理100000个数据条目。

关于“在处理过程中显示图像”,您将显示图像,然后setTimeout延迟您的工作,当您完成工作后,删除图像并将数据设置为$scope

您无法在执行过程中刷新HTML,因为Web页面是单线程的,这意味着当CPU正在计算时,无法执行其他任何操作。 (从技术上讲,网络工作者可以帮助派生多个线程,但实际上,您不需要这样做)。

因此,您要单击的就是说,启用一个图像,然后等待angular用该图像更新DOM,然后运行繁重的代码。

要实现这一点,您需要使用$timeout服务,方法是:

$scope.onClick = function() {
  // Set the model to display an image
  $scope.displayImage = true;
  // Wait for angular to digest the current cycle and update the DOM
  $timeout(function() {
    // Do heavy stuff, and at the bottom of the code update the model to hide the image
    $scope.doHeavyStuff();
    $scope.displayImage = false;
  });
}

在您的HTML中,您只需要

<img ng-show = "displayImage" src = "some_url">
<div ng-hide = "displayImage"> Heavy stuff done :) </div>

现在,如果您在此步骤上遇到ng-show问题,请打开另一个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM