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

时间:2015-11-19 00:59:58

标签: javascript angularjs angularjs-scope page-refresh

我在第三页的页面中有一点角度html。

一切正常,代码工作正常,指令工作正常(除了" ng-show"它从不起作用,但这并不重要)。

但是我有一个繁重的代码,只需点击一下按钮(ng-click)。在执行期间,一切都冻结了,好吧,这是预期的。

但我非常希望能够制作一个" img"在执行期间出现,但似乎在代码期间没有更新(代码之后一切都完全更新,但代码期间完全更新)。

我怎样才能刷新"角度html"期间"在" ng-click"中执行代码?

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

修改

感谢以下答案:错误确实是因为" apply / digest"已经在进行中了。通过使用所示的同步方法,我可以使用" apply"没有问题。

4 个答案:

答案 0 :(得分:1)

在图像上进行ng-show怎么样?您可以使用div来占据希望使用

显示图像的整个部分
<div ng-show="loading" class="some-class-to-display-image"></div> 

然后在您处理/拨打电话等时转向$scope.loading = true;。您可以使用承诺并在请求中使用.finally()并设置$scope.loading = false;以停止动画。

答案 1 :(得分:1)

首先在$ scope.apply()中包装您想要执行的代码应该有效,除非您正在进行&#34; $摘要已经在进行中&#34;发生错误,因为一次只能运行一个摘要周期。

如果出现这种情况,您可以尝试在加载图像显示在$ timeout或$ evalAsync(Angular v1.2.x&amp; above)之后包装您要执行的代码,这将确保2个消化周期不会发生冲突,即

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

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

答案 2 :(得分:1)

JavaScript在浏览器环境中的工作方式是执行一个javascript块直到完成,无论您使用AngularJS还是vanilla 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) + "%";
  }
}

它不会按预期更新浏览器中的进度条div,但会冻结浏览器,直到onDivClick完成。这与AngularJS没有什么不同,AngularJS处理大量数据不会更新您的UI。

要处理大量数据,您需要拆分工作并使用任何类型的&#34; future&#34; /&#34; promise&#34; /&#34; delay&#34;技术 - 对于这个例子:

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

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

关于&#34;在过程中显示图像&#34;,您将显示图像,然后setTimeout延迟工作,当您的工作完成后删除图像并设置数据到$scope

答案 3 :(得分:1)

你不能在执行期间刷新HTML,作为单线程的网页,这意味着当CPU在计算时,没有别的办法可以做。 (从技术上讲,Web工作者可以帮助分叉多个线程,但实际上,您不需要这样做。)

所以你想点击的是,启用一个图像,然后等待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问题,请打开另一个问题。