5

AngularJS+Node.jsアプリに無限スクロール機能を実装しました。

これはこのJSfiddleに基づいており、同じように機能します。http://jsfiddle.net/vojtajina/U7Bz9/ HTML

<div id="fixed" when-scrolled="loadMore()">
  <ul>
   <li ng-repeat="i in items">{{i.id}}</li>
  </ul>  
</div>​

Javascript:

function Main($scope) {
  $scope.items = [];

  var counter = 0;
   $scope.loadMore = function() {
     for (var i = 0; i < 5; i++) {
        $scope.items.push({id: counter});
        counter += 10;
     }
   };

  $scope.loadMore();
}

angular.module('scroll', []).directive('whenScrolled', function() {
  return function(scope, elm, attr) {
    var raw = elm[0];

    elm.bind('scroll', function() {
        if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
            scope.$apply(attr.whenScrolled);
        }
    });
  };
});

</ p>

無限スクロールを実装する理由は、ユーザーがすべてを表示したくない場合を除いて、1000の結果すべてとそれに対応する画像を読み込まないことで、ユーザーの帯域幅を節約するためです。

ただし、AngularJSフィルターを使用して結果内を検索すると、問題が発生します。もちろん、すべての結果がそこにあるわけではないため(ユーザーが一番下までスクロールしていない限り)、検索では必要な結果の一部しか返されません。

次に、検索機能を正しく機能させるために無限スクロール機能を削除しましたが、ページを開くと、ブラウザが上から画像の読み込みを開始するときに、Chromeで新しい問題が発生しました(Firefoxではありません)。次に、「z」で始まるもの(結果の一番下)を検索して結果をフィルタリングすると、Firefoxはフォーカスを切り替え、最初に「z」で始まる結果をロードします(その後、表示されるのはそれらだけです)。ただし、Chromeはリストを介して読み込みを続行するため、アプリ内のすべての画像が読み込まれると、ユーザーには検索結果( "z"の場合)のみが表示されます。

私は、Angularが結果に対して無限スクロールと適切な検索フィルターの両方を同時に提供する方法を探しています。これが不可能な場合は、最初にChromeに表示画像をロードさせる方法。

私は現在、スコープ内のさまざまな配列を使って奇妙なことを試していますが、これまでのところ運がありません。

4

2 に答える 2

8

ここの何人かが同様の問題を抱えていて、私自身も苦労していたので、時間をかけて機能するフィドルを作成しました(私の場合)。

https://jsfiddle.net/lisapfisterer/Lu4sbxps/

主なアイデアは、無限スクロールの関数呼び出しを使用して limitTo 値を動的に拡張することです

<div infinite-scroll="loadMore()" infinite-scroll-distance="20">
    <tr data-ng-repeat="logEvent in logEventFilter = (logEvents | filter:searchTerm | limitTo:numberToDisplay) track by $index">
        <td> {{$index}} </td>
        <td> {{logEvent.name}} </td>
        <td> {{numberToDisplay}} </td>
    </tr>
</div>

loadMore は制限を増やすだけです

$scope.loadMore = function() {
    if ($scope.numberToDisplay + 5 < $scope.logEvents.length) {
        $scope.numberToDisplay += 5;
    } else {
        $scope.numberToDisplay = $scope.logEvents.length;
    }
};
于 2016-02-09T13:40:46.157 に答える
1

あなたがやりたいことは「不可能」ではありませんが、確かに少し複雑になるでしょう。

  • サーバーにすべての「フィルタリング」を実行させて、返されたページ分割された値がフィルターの適切な値であることを確認します。
  • サーバーが結果を返したら、イメージ タグの src 属性を除くすべての HTML を画面にレンダリングします。この方法では、どの画像もまだロードを開始しません。
  • 適切な「ページ」までスクロールします。
  • 画像がロードされる前のすべての高さが同じであることを確認してください。次に、JS マジックを実行して、どの画像が表示されているかを判断します。
  • 可視画像のみの src 属性を設定し、それらの「ロード」イベントをサブスクライブし、すべてのロードが完了すると完了する $q promise を作成します。
  • その promise が完了したら、残りの画像の src 属性を設定して、残りの画像が読み込まれるようにします。
于 2012-10-29T13:51:42.833 に答える