2013-07-05 11 views
7

Próbuję znaleźć sposób na załadowanie dużych ilości danych (do 1000 wierszy) na stronę, bez stronicowania. Pierwszą przeszkodą w tym było kwerendy DB równolegle ukąszenie średnich kawałków, które zrobiłem z pomocą roztworu w How to make sequentially Rest webservices calls with AngularJS?Ładowanie dużych zestawów danych za pomocą AngularJS

biegnę na dwa problemy z tym, co już wdrożone jednakże:

  1. Każdy zwracany obiekt jest przekazywany do tablicy, która następnie jest zwracana jako tablica, z której korzysta Angular do wiązania. tj [[{klucz: wartość, klucz: wartość, klucz: wartość}, {klucz: wartość, klucz: wartość, klucz: wartość}], [{klucz: wartość, klucz: wartość, klucz: wartość}, {klucz: value, key: value, key: value}]] Jako takie nie mogę użyć ng-repeat = "item in data", ponieważ dane są tablicą tablic. Wykonanie "pozycji w danych [0]" sprawia, że ​​przedmiot jest dostępny. Konkatenacja wydaje się być odpowiedzią, ale nie udało mi się znaleźć sposobu, który by działał.

  2. Wykonuję wiele żądań do bazy danych, a każde żądanie jest zwracane poprawnie, ale strona nie wyświetla się, dopóki wszystkie żądania nie zostaną zakończone - co całkowicie neguje zasadność wykonywania wielu żądań w pierwszej kolejności.

Więc patrząc na mój kod, jak mogę napisać go ponownie, aby rozwiązać te dwa problemy? Czy dane są zwracane jako jedna tablica, a dane są renderowane za każdym razem, gdy zapytanie zostanie zakończone?

app.factory('ScanService', function($http, $q) { 
    function fetchOne(stepCount) { 
    return $http({ 
     method: 'GET', 
     url: '/index.php/scans', 
     params: {step:stepCount} 
    }) 
    .then(function onSuccess(response) { 
     return response.data; 
    } 
    return { 
     fetchAll: function(steps) { 
     var scans = []; 
     for (var i = 1; i <= steps; i++) { 
      scans.push(fetchOne(i)); 
     } 
     return $q.all(scans); 
     } 
    }; 
}); 

app.controller.ScanCtrl = function($scope, $q, ScanService) { 
    $scope.scans = ScanService.fetchAll(10); 
}; 

Kontynuacja

Dodam, że udało się uzyskać ten działa w oparciu o rozwiązania poniżej i angular.forEach(). Nie można zasugerować, aby ktoś pracujący z "dużymi danymi" podążał tą trasą. W około 1000 wierszy przeglądarka była przytłoczona i zaczęła znacznie spowalniać. Próba filtrowania za pomocą filtru angular.filter również uległa znacznemu opóźnieniu do momentu zawężenia wyników. Z drugiej strony kilkaset wierszy działało dobrze i pozwalało na natywne filtrowanie - co było kluczowym celem dla mojej implementacji.

+3

Kto ze zdrowym umysłem chce patrzeć na tysiące rzędów danych? – Bart

+0

@Bart Niestety, musiałem to również zrobić. Niektórzy analitycy biznesowi wygodnie pracują z tysiącami wierszy danych Excela i potrzebują podobnego widoku w Internecie. Podczas gdy ja z całym sercem nie zgadzałem się z nimi, czasami musisz zrobić to, co klient chce :( – Terry

+0

@Bart, który chce przejść przez 100 stron po 10 wierszy? Przypuszczam, że to naprawdę ja szukam alternatywnych rozwiązań paradygmatu stronicowania i nieskończonego przewijania nie rozwiązuje problemu, z którym się borykam. Ogólnie chodzi o to, że ładujesz swoje dane, a następnie filtrujesz je w Angular, więc niekoniecznie będziesz patrzył na 1000 wierszy - ale mógłbyś, gdybyś był szalony. – iamsar

Odpowiedz

6

Nie można naprawdę $ q.all obietnic razem (co czyni je jedną wielką obietnicą, która się powiedzie lub nie powiedzie się razem), jeśli chcesz traktować każdy indywidualnie (wyświetlić każdy z nich indywidualnie).

Popchnę rzeczy, które odzyskasz, gdy tylko je dostaniesz. Poniżej znajduje się przykład:

function MyCtrl($scope, $timeout, $q) { 
     var fetchOne = function() { 
      var deferred = $q.defer(); 
      $timeout(function() { 
       deferred.resolve([random(), random() + 100, random() + 200]); 
      }, random() * 5000); 
      return deferred.promise; 
     }; 

     $scope.scans = []; 
     for (var i = 0; i < 2; i++) { 
      fetchOne().then(function(items) { 
       angular.forEach(items, function(item) { 
        $scope.scans.push(item); 
       }); 
      }); 
     }; 
    } 

Oto skrzypce pokazywanie go w akcji: http://jsfiddle.net/wWcvx/1/

Jest to problem tutaj gdzie kolejność elementów są oparte na kiedy zostały zwrócone, a nie na swojej oryginalnej kolejności zgłoszenia. Pozwolę ci wymyślić to samo.

+0

Dzięki za odpowiedź. To potrwa kilka tygodni, zanim wrócę do biura, aby przetestować to, ale nie mogę się doczekać, kiedy go wykorzystam. Sam porządek właściwie nie powinien mieć znaczenia. – iamsar

+2

W końcu udało mi się nadać temu inny wygląd. Pięknie pracował. O wiele łatwiej niż początkowo próbowałem to zrobić. Kluczową sprawą była funkcja "kątowa. Na każdy". – iamsar

Powiązane problemy