Zugriff auf eine computed property einer Kind-Komponente in VueJs | Arroba IT
Zum Inhalt springen
vuejs datatables

Zugriff auf eine computed property einer Kind-Komponente in VueJs

27. Nov 2017

Wenn man von jQuery kommt wird man an DataTables wahrscheinlich nicht vorbeigekommen sein. Doch wie setzt man diese VueJS um. Es gibt einige Implementierungen, aber keine kommt auch nur annähernd an DataTables von JQuers heran. Meiner Meinung nach ist die beste Option ist das Package DataTable von Spatie. Es ist schnell und gut dokumentiert und ... nun ja von Spatie. Da ist gute Qualität vorprogrammiert – im wahrsten Sinn des Wortes.

ich benutze das Package seit einiger Zeit in einem meiner Projekt. Mit der Lebensdauer der Software wachsen auch die zu verwaltenden Daten und ich brauchte eine Info über die Zeilenanzahl in der Fußzeile. Die Demo-Seite zeigt mit der Summe aller Lieder nicht ganz was ich möchte, da ich nur die Gesamtzahl der Zeilen brauche, aber ich habe die Idee verstanden: Einfach die Länge des Arrays anzeigen, die ich an die Komponente übergeben habe und voilá, die Fußzeile zeigte die 30 Einträge korrekt an.

Aber ... das funktioniert nur so lange, bis man einen Filter wie auf der Demo-Seite hat; dann werden immer noch 30 angezeigt, auch wenn man die Tabelle auf 10 gefiltert hat. Auf der Demoseite kann man das gut nachvollziehen: Einfach mal "Ringo" in den Filter eingeben. Die Einträge werden zwar auf eine Zeile gefilter, aber die Summe unten bleibt gleich.

In der Dokumentation des Packages kann man sehen, dass man einen scope an das FooterTemplate mit den Zeilen übergeben kann ... aber dies enthält auch nur die ursprünglichen und nicht die gefilterten Daten.

Hinweis: Unter VueJS 2.5 oder höher ist slot-scope anstelle von scope zu verwenden.

Nach einem Blick in den Code habe ich dann herausgefunden, dass die Komponente eine computed property namens displayedRows bereitstellt, die - wie der Name schon sagt - die angezeigten Zeilen oder mit anderen Worten die gefilterten Zeilen speichert. Wie kann ich auf diese Eigenschaft zugreifen?

Zunächst fügte ich der Komponente table die Eigenschaft ref hinzu: table-component(ref="table"). Diese fungiert als Zugang zu den Interna der Tabelle. Mit this.$refs.table.displayedRows.length erhalte ich die aktuelle Anzahl der gefilterten Zeilen. Um fortzufahren, bitte Folgendes beachten:

  1. es ist nicht möglich, auf $refs in einer computed property zuzugreifen, da die untergeordnete Komponente zum Zeitpunkt der Erstellung der computed property möglicherweise noch nicht geladen ist

  2. selbst wenn 1) nicht zuträfe, würde die Verwendung in einer computed property nicht funktionieren, da $refs nicht reaktiv ist, d.h. es bleibt für immer auf dem ursprünglichen Wert

  3. Und wegen 2) kann man es nicht in mounted() verwenden und den Wert einer lokalen Datenvariablen zuweisen

Und was ist mit einem Watcher? Ein normaler Watcher wird nicht funktionieren, weil $refs undefiniert sein kann, wenn es gemountet wird, wie bereits erwähnt. Wie kann ich sie also überwachen, sobald sie gemountet ist? Schauen wir uns nun den finalen Code an:

1<template>
2 <table-component
3 :data="[
4 { firstName: 'John', birthday: '04/10/1940'},
5 { firstName: 'Paul', birthday: '18/06/1942'},
6 { firstName: 'George', birthday: '25/02/1943'},
7 { firstName: 'Ringo', birthday: '07/07/1940'},
8 ]"
9 sort-by="firstName"
10 sort-order="asc"
11 ref="table"
12 >
13 <table-column show="firstName" label="First name"></table-column>
14 <table-column show="birthday" label="Birthday" :filterable="false" data-type="date:DD/MM/YYYY"></table-column>
15 <template slot="tfoot">
16 <th>&nbsp;</th>
17 <th>Total: {{ sum }}</th>
18 </template>
19 </table-component>
20</template>
21<script>
22 // some code
23 data() {
24 return {
25 sum: 0,
26 }
27 },
28 
29 mounted() {
30 this.$watch(() => this.$refs.table.displayedRows.length, (value) => { this.sum = value;})
31 },
32</script>

In der Fußzeile wird nun die aktuelle Anzahl der gefilterten Zeilen angezeigt.