hmm: Angular 8: NgxPaginationModule soll mit RESt API arbeiten

Hi,

ich möchte in Angular 8 das NgxPaginationModule verwenden. Kann ich dieses Modul mit meiner REST API kommunizieren lassen? Falls ja, wie?

Ich bekomme immer 15 Datensätze von meiner REST API, diese 15 möchte ich mir durch mein NgxPaginationModule anzeigen lassen. Leider weiß ich nur wie das geht, wenn mein Client sämtliche Daten kennt. Leider finde ich auch keine Beschreibung im Netz die zu meinem Problem passt.

akzeptierte Antworten

  1. Tach!

    ich möchte in Angular 8 das NgxPaginationModule verwenden. Kann ich dieses Modul mit meiner REST API kommunizieren lassen? Falls ja, wie?

    Nein, das ist auch nicht nötig. Der Paginator ist nur für die Pagination nötig, nicht für die Anzeige und das Holen der Daten

    Ich bekomme immer 15 Datensätze von meiner REST API, diese 15 möchte ich mir durch mein NgxPaginationModule anzeigen lassen.

    Siehe Dokumentation zum Server-Side Paging, du musst totalItems angeben, damit er sich richtig anzeigen kann, auch wenn weniger Daten vorhanden sind.

    dedlfix.

    1. danke.

      this.config = {
        itemsPerPage: 15,
        currentPage: 1,
        totalItems: xyz
      };
      

      <pagination-controls (pageChange)="pageChanged($event)"></pagination-controls>

      Ich kann in pageChanged neue Daten von meiner REST APIanfordern die dann auch angezeigt werden wenn zb auf Page 2 geklickt wird. Aber ich kann die Daten von Page 1 nicht löschen, oder? Sollte ich bereits angeforderten Daten löschen oder lässt man die idr im Client stehen?

      Beispiel: Jemand klickt auf Page 1, dann auf 2 dann auf 3 etc., dann würde mein Array mit den Daten entsprechend anwachsen, damit das Framework die anzuzeigenden Daten unter dem entsprechenden Index findet, richtig?

      1. hm... angenommen das Datenarray kennt nur die Daten von Page 1 und der Anwender klickt auf Page 3 ohne auf page 2 geklickt zu haben, dann müsste ich mir die Daten von Page 3 holen und itemsPerPage viele Elemente vom Array befüllen, oder geht das besser?

        1. Hallo hmm,

          hm... angenommen das Datenarray kennt nur die Daten von Page 1 und der Anwender klickt auf Page 3 ohne auf page 2 geklickt zu haben, dann müsste ich mir die Daten von Page 3 holen und itemsPerPage viele Elemente vom Array befüllen, oder geht das besser?

          Vorweg: ich kenne mich mit Angular nicht aus. Aber in React würde man das so lösen, dass man nicht an das Array anhängt, sondern dass man das Array überschreibt mit den Daten von Seite 3, so dass nur Seite 3 angezeigt wird. Das kann man in Angular sicher ähnlich lösen.

          Das fetch-Result von Seite 1 würde man dann entweder in einem Caching-Layer cachen oder neu abrufen, wenn der User zu dieser Seite zurück kehrt. Oder beides: erst den gecachten Zustand anzeigen und wenn das fetch-Result da ist dieses anzeigen.

          Freundliche Grüße,
          Christian Kruse

          1. danke. Mir ist leider nicht ganz klar wie das Framework beim Pagination arbeitet.

            Ich habe ein currentPage, ein totalItems, ein itemsPerPage und ein Array collection.

            Ich fordere für Seite 3 neue Daten für collection an und setze currentPage auf 3. Ich vermute, dass das Framework dann Daten von 2itemsPerPage bis 3itemsPerPage aus collection anfordert. Meine Datenanforderungsmethode kann die anderen Felder des Array "löschen". Das ist trotzdem etwas unschön.

            Die Datenanforderungsmethode wird bei jedem Pagination-Klickevent aufgerufen.

            1. Tach!

              danke. Mir ist leider nicht ganz klar wie das Framework beim Pagination arbeitet.

              Das Angular-Framework hat damit nichts zu tun, sondern du muss dich informieren, wie diese 3rd-party Pagination-Komponente funktioniert.

              Ich habe ein currentPage, ein totalItems, ein itemsPerPage und ein Array collection.

              In collection sind entweder die gesamten Daten, dann aber ohne totalItems, und die Daten der aktuellen Seite werden von der paginate-Pipe daraus gefiltert. Oder totalItems ist gesetzt, dann sind in collection lediglich die Daten der aktuellen Seite.

              So ist das dokumentiert.

              dedlfix.

          2. Tach!

            hm... angenommen das Datenarray kennt nur die Daten von Page 1 und der Anwender klickt auf Page 3 ohne auf page 2 geklickt zu haben, dann müsste ich mir die Daten von Page 3 holen und itemsPerPage viele Elemente vom Array befüllen, oder geht das besser?

            Vorweg: ich kenne mich mit Angular nicht aus. Aber in React würde man das so lösen, dass man nicht an das Array anhängt, sondern dass man das Array überschreibt mit den Daten von Seite 3, so dass nur Seite 3 angezeigt wird. Das kann man in Angular sicher ähnlich lösen.

            Ja, wobei man hier auch beachten muss, wie es die Komponenten von ngx-pagination gerne hätten. Man hat als Datenauflistung sowas wie:

            <ul>
              <li *ngFor="let item of collection | paginate: { itemsPerPage: 10, currentPage: p, totalItems: ti }"> ... </li>
            </ul>
            

            Das heißt, in collection sind (nur) die Daten der aktuellen Seite, wenn man Server-Side Paging betreibt und totalItems setzt. Dieser Variable (sprich: Eigenschaft der Component) muss man einen neuen Wert (ein neu erzeugtes Array) zuweisen, damit die Change Detection die Änderung mitbekommt. Daten in dem bestehenden Array lediglich zu verändern ergibt keine erneute Ausgabe, weil die Referenz des Arrays geprüft wird und nicht dessen Inhalt.

            Das fetch-Result von Seite 1 würde man dann entweder in einem Caching-Layer cachen oder neu abrufen, wenn der User zu dieser Seite zurück kehrt. Oder beides: erst den gecachten Zustand anzeigen und wenn das fetch-Result da ist dieses anzeigen.

            Vielleicht, vielleicht auch nicht. Kommt darauf an, wie aktuell die Daten sein sollen und wie schnell sie sich serverseitig ändern.

            dedlfix.

            1. Hallo dedlfix,

              Dieser Variable (sprich: Eigenschaft der Component) muss man einen neuen Wert (ein neu erzeugtes Array) zuweisen, damit die Change Detection die Änderung mitbekommt. Daten in dem bestehenden Array lediglich zu verändern ergibt keine erneute Ausgabe, weil die Referenz des Arrays geprüft wird und nicht dessen Inhalt.

              Naja, na klar, deshalb schrieb ich ja „überschreiben.“ Das ist in React auch so. Sub-Komponenten werden nur neu gerendert, wenn sich ihr State oder ihre Props ändern.

              Das fetch-Result von Seite 1 würde man dann entweder in einem Caching-Layer cachen oder neu abrufen, wenn der User zu dieser Seite zurück kehrt. Oder beides: erst den gecachten Zustand anzeigen und wenn das fetch-Result da ist dieses anzeigen.

              Vielleicht, vielleicht auch nicht. Kommt darauf an, wie aktuell die Daten sein sollen und wie schnell sie sich serverseitig ändern.

              Ja. Deshalb ja „oder.“

              Freundliche Grüße,
              Christian Kruse

              1. Tach!

                Dieser Variable (sprich: Eigenschaft der Component) muss man einen neuen Wert (ein neu erzeugtes Array) zuweisen, damit die Change Detection die Änderung mitbekommt. Daten in dem bestehenden Array lediglich zu verändern ergibt keine erneute Ausgabe, weil die Referenz des Arrays geprüft wird und nicht dessen Inhalt.

                Naja, na klar, deshalb schrieb ich ja „überschreiben.“ Das ist in React auch so. Sub-Komponenten werden nur neu gerendert, wenn sich ihr State oder ihre Props ändern.

                Ich wollte das nur nochmal hervorheben, dass es nicht nur eine Konvention ist, die man ignorieren könnte, sondern notwendig, damit die Change-Detection ein erneutes Rendern anstößt. hmm hatte ja mit dem Gedanken gespielt, dass Array zu verändern, was aber nicht zielführend ist, und das obendrein weder für die Angular-Mechanismen noch für die Arbeitsweise des verwendeten Paginators. Mir schien, dass ihm dieses Überschreiben-Müssen noch nicht ganz klar war.

                dedlfix.

                1. habs gerade getestet. das framework arbeitet doch so wie man es braucht. wenn ich das array nach jedem paging event leere und nur die notwendigen daten reinschreibe passt alles.

                  danke!

                  1. Tach!

                    habs gerade getestet. das framework arbeitet doch so wie man es braucht. wenn ich das array nach jedem paging event leere und nur die notwendigen daten reinschreibe passt alles.

                    Das Array zu manipulieren ist nicht der von Angular vorgesehene Weg. Statt das Array zu leeren, nimm besser ein neues und weise es der collection-Eigenschaft zu (oder wie auch immer die bei die heißt). Der Aufwand ist derselbe. Ich vermute, dass es bei der letzten Seite Probleme gibt, wenn diese weniger Elemente hat.

                    Wenn man es "richtig" macht, würde man allerdings für collection ein Observable von RxJS nehmen und die neuen Daten per next() übergeben.

                    dedlfix.

                    1. Das RxJS teste ich vielleicht. Vorher muss ich mir aber angucken wie ich das Sortieren der Daten hinkriege. Meine REST API kann mir Daten nach einer bestimmten Spalte sortieren, aber wie ich passende Sorting-Knöpfe im Angular Paging realisiere, muss ich mir noch angucken.

                      Andere kleine Frage:

                      this.httpClient.get('/rest/ui/releases?size=15&page=' + 0, { headers: this.headers }).toPromise().then(data => {
                        //var jsonData = JSON.stringify(data);
                        var countMax = data.headers.get("X-Total-Count");
                        for (var i = 0; i < 15; i++) {
                          let obj = {releaseVersion: data[i].releaseVersion};
                          this.collection.push(obj);
                        }
                      });
                      

                      Das Auslesen eines Headerparameters per var countMax = data.headers.get("X-Total-Count"); geht nicht, weil Data kein response ist. Wie ließt man in Angular Headerparameter aus?

                      1. Tach!

                        Das Auslesen eines Headerparameters per var countMax = data.headers.get("X-Total-Count"); geht nicht, weil Data kein response ist. Wie ließt man in Angular Headerparameter aus?

                        Man lese die Dokumentation von HttpClient.get(), welchen Parameter man angeben muss, um die komplette Response zu bekommen und nicht nur die Daten.

                        Außerdem ist es empfehlenswert, toPromise() zu vermeiden, wenn man nicht aus irgendeinem Grund auf Promises angewiesen. RxJS hat mit .subscribe() einen gleichwertigen/einfacheren Weg, den man statt .toPromise().then() verwenden kann.

                        dedlfix.