【问题标题】:Show filtering div while ng-repeat is working在 ng-repeat 工作时显示过滤 div
【发布时间】:2015-05-20 19:42:34
【问题描述】:

我有一个长时间运行的任务,我想显示一个简单的 div 来提醒用户并让他们等待。

我有一个自定义过滤器需要大约 10 秒才能应用。这大约是初始页面加载时间的三倍,因此仅此一项就是一个问题,但如果我可以显示一个警告他们任务正在内存中工作的 div,我的用户会在某种程度上感到满意。

我正在使用 ng-show="filteringTasks" 变量,但它没有显示 div,因为 Angular 似乎正忙于过滤过程并且用户界面没有更新。

<div ng-show="filteringTasks">Filtering Tasks...Please wait </div>

所有任务都是在页面初始加载时加载的,因此在这种情况下,“数据”是数据库中的所有 400 多条记录。这是 ng-repeat 的 html:

<div ng-repeat="task in filteredTasks = 
    ( data | filter:searchText | statusFilter:statusOptions
    orderBy:predicate:reverse ) track by task.id " 
    on-finish-render="ngRepeatFinished">

ng-repeat 完成时会触发指令“ngRepeatFinished”。这工作正常。

过滤器正在为每个任务寻找五个状态(过滤器数组)中的一个或多个。如果 task.status 与请求的状态匹配并且过滤器为真,则将任务添加到结果中。

这是过滤器:

ppApp.filter('statusFilter', [ function ( $filter ) {
return function( input, filter ) {
    if ( input ) {
        var result = [];
        angular.forEach(input, function ( task ) {
            angular.forEach( filter, function( ans, status ) {
                if ( task.status == status && ans ) {
                    result.push( task );
                }
            });
        });
        return result;
        }
    };
}]);

最后,为了提示用户,我在控制器中添加了这个:

$scope.initialPageLoad=true; 
$scope.$watch("statusOptions['incomplete']", function() {
    if ( $scope.initialPageLoad ) {
        $scope.initialPageLoad = false;
    } else {
        alert('this may take a while');
        $scope.filteringTasks=true;
    }
});

这个概念是提醒用户注意长时间运行的任务并通过设置 $scope.filteringTasks=true; 来显示 div;一种想法是实现无限滚动指令并在完成时显示结果。另一个是有某种进度条,但如果界面甚至不显示一个简单的 div 似乎就没有用了!我真的不知道为什么过滤器需要这么长时间才能应用,但代码会正确触发。

我怎样才能可靠地让用户知道 ng-repeat 在幕后工作?

【问题讨论】:

  • 您的 ng-repeat 在 ng_show 之后仍然不显示“过滤任务?”
  • 没错。 div 仅在一切完成之前显示一毫秒。它在 ng-repeat 工作时不显示。
  • 我知道这不是问题,但您确实提到您不知道为什么运行需要这么长时间,因此仅使用标准 for 循环可能值得重写。它应该更快:jsperf.com/angular-foreach-vs-native-for-loop/3,这里是原生/jQuery 测试:jsperf.com/for-vs-foreach/37
  • 我修改了过滤器以使用本机 forEach 并显式迭代过滤器对象。我没有发现性能有很大的提高,但这个想法是有效的。
  • 在 ng-repeat 中使用 "bind once" 提高效率有意义吗?如果是这样,有人可以告诉我如何正确地做到这一点。我将 ng-repeat 修改为: task in ::filteredTasks 但这似乎不起作用。似乎这可以通过将性能提高到我不需要显示 div 来过滤数据的程度来解决问题。

标签: javascript angularjs


【解决方案1】:

解决这个问题的一种方法是创建两个 html 文件:一个使用 ng-show,另一个使用 ng-repeat。然后使用 Angular stateProvider 和 Angular ui-route-provider 来加载这两个 html 文件。因此,最初您的第一个 html 将完全加载,然后,您的 ui-router 将加载第二个 html。这也可以在用户过滤器操作中完成。

注意:这不是这些提供程序的主要目的,但会完成任务。

【讨论】:

  • 这是一个有趣的想法,但是页面现在加载了一些部分 html 文件,每个加载并通过使用 $scope.$emit('LOAD') 和 UNLOAD 调用让用户知道.当一切都在内存中时选择过滤器时会出现问题......所有任务都在 $scope.data 对象中。当用户单击过滤器(例如“不完整”)时,它会触发 statusFilter 并且 Angular 开始工作,而不会触发我可以捕获的任何其他东西(据我所知)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 1970-01-01
相关资源
最近更新 更多