简体   繁体   English

AngularJS如何使用过滤器对图像进行延迟加载

[英]AngularJS how to do lazy load of images with filters

I'm developing an angular application where the main page loads 1000 images, but the user can only look at 20 at a time. 我正在开发一个角度应用程序,其中主页面加载1000个图像,但用户一次只能查看20个。 I will also have several filters on my list, so that it can be filtered and sorted based on different criteria. 我的列表中还有几个过滤器,因此可以根据不同的标准对其进行过滤和排序。

I've tried http://binarymuse.github.io/ngInfiniteScroll/# and http://ngscroller.herokuapp.com/ but neither seems to work that well. 我已经尝试过http://binarymuse.github.io/ngInfiniteScroll/#http://ngscroller.herokuapp.com/,但似乎都没有那么好用。

Ngscroller does work but it breaks when I try to apply my filters. Ngscroller确实可以工作,但是当我尝试应用我的过滤器时,它会中断。 I also prefer this one since it does not require me to include jquery. 我也更喜欢这个,因为它不需要我包含jquery。 Are there any simple directives out there that can do what I need to? 有没有可以做我需要的简单指令? I'm trying to speed up my web page but I don't want to reinvent the wheel if there is something out there which already accomplishes this. 我正在尝试加速我的网页,但如果有一些已经完成此操作的东西,我不想重新发明轮子。

Here is my attempt with ngScroller: http://plnkr.co/edit/r0uhV3OxT2USxmrBQk22?p=preview 这是我对ngScroller的尝试: http ://plnkr.co/edit/r0uhV3OxT2USxmrBQk22?p = preview

<div class="content" ng-controller="MainController" ng-scroller="content">
  <ul class="list" ng-scroller-repeat="item in items | filter:idOver500k | orderBy:predicate:!reverse">
    <li class="item">{{item.text}}</li>
  </ul>
</div>

The scroll works without the filter and orderBy, but I'm looking for a method that will handle all cases. 滚动工作没有过滤器和orderBy,但我正在寻找一种方法来处理所有情况。

It takes at least 3 seconds longer to load my page than it does if I remove the images. 加载页面至少需要3秒才能删除图像。 It looks like angular is loading only when all of the images are obtained. 看起来只有在获得所有图像时才加载角度。 What is the best way to handle this? 处理这个问题的最佳方法是什么?

Thank you! 谢谢!

Demo with ng-infinite-scroll : http://plnkr.co/edit/O5w0Fp 使用ng-infinite-scroll进行演示: http//plnkr.co/edit/O5w0Fp

ng-infinite-scroll has different mechanism with ng-scroller . ng-infinite-scrollng-scroller有不同的机制。 infinite-scroll will trigger a loadMore function when user scroll to the bottom. 当用户滚动到底部时,无限滚动将触发loadMore函数。 You can define loadMore function yourself. 您可以自己定义loadMore函数。

I created a lazyLoad filter to only only return part of the filtered items, managed by counter variable. 我创建了一个lazyLoad过滤器,只返回由counter变量管理的部分过滤项。 When scroll to the bottom, counter will be incremented by one to return more items from lazyLoad filter. 滚动到底部时, counter将加1以从lazyLoad过滤器返回更多项目。

When user change the order by parameter, counter will be reset to 1. 当用户通过参数更改订单时, counter将重置为1。

When counter equals 1 , it will load the first 30 items. counter等于1 ,它将加载前30个项目。

Notes 笔记

It may have problem if the height of document.body is less than the height of window , because that way document will not be able to scroll thus will not trigger scroll event. 如果document.body的高度小于window的高度,则可能有问题,因为该方式文档将无法滚动,因此不会触发scroll事件。 You have to manually check the heights and trigger loadMoreItems accordingly. 您必须手动检查高度并相应地触发loadMoreItems

The problem will occur while page initialize or counter reset. 页面初始化或counter重置时会出现此问题。

I added adjustCounter function to run after reset the counter. 我在重置计数器后添加了adjustCounter函数来运行。 ng-infinite-scroll will handle this when page load internally. ng-infinite-scroll将在内部页面加载时处理此问题。

Looks like this isn't going to work with a dynamic filter without fixing ngScroller. 在没有修复ngScroller的情况下,这似乎无法使用动态过滤器。

The offending code seems to be in the ng.Scroller.prototype.compile function: 有问题的代码似乎在ng.Scroller.prototype.compile函数中:

var exp = carousel.getAttribute('ng-scroller-repeat');
var keys = exp.split(/\s+in\s+/);

Where ngScroller basically splits the attribute without looking at filters or the like. 其中ngScroller基本上拆分属性而不查看过滤器等。

One possibe workaround is like @Daiwei suggests and filter before binding. 一个可能的解决方法就像@Daiwei建议并在绑定之前过滤。 Not such a bad solution as this is a lot faster anyway. 这不是一个糟糕的解决方案,因为无论如何这要快得多。

  app.controller('MainController', function ($scope) {
    $scope.allItems = generateItems(1000);
    $scope.items = $scope.allItems.reduce(function(previous, item){
      if (item.id > 500000)
      {
        previous.push(item);
      }
      return previous;
    },[]); 
  });

See this Plunker for an example. 有关示例,请参阅此Plunker

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

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