Vuetify :: Aprire programmaticamente la riga di dettaglio
Per il prossimo rilascio di PiCockpit v2.0, sto preparando un'applicazione GPIO.
Le voci GPIO sono righe di tabella - e per configurarle, vogliamo essere in grado di accedere alla riga di dettaglio cliccando sul pulsante configure:
facendo clic sul chevron o sul pulsante di configurazione si aprirà la riga di dettaglio:
Ecco il template Vue corrispondente:
<v-data-table
:headers="gpioInputTableHeaders"
:items="gpioInputTableData"
:loading="caricamento"
item-key="bcm_id"
loading-text="in attesa di dati ... "
intestazione fissa
mostra-espandi
:expanded.sync="gpioInputTableExpanded"
class="elevazione-1″
>
.
<span v-if="”!onlineStateBinary”"><i class="”fa" fa-warning”></i> </span>
<span v-if="”item.state" ><v-icon x-small>mdi-arrow-up-bold</v-icon>{{item.high}}</span>
<span v-else-if="”item.state" ><v-icon x-small>mdi-arrow-down-bold</v-icon>{{item.low}}</span>
<span v-else-if="”item.state" >N/A</span>
<span v-else-if="”item.state" >N/A</span>
<span v-else>ERRORE</span>
</template>
<template v-slot:item.action="{ item }">
<v-btn
class="mr-2″
colore="primario"
piccolo
@click.ctrl.exact="configGpioAll('input', item)"
@click.exact="configGpio('input', item)"
>
mdi-hammer-wrench
Configurare
</v-btn>
<v-btn
class="mr-2″
colore="errore"
piccolo
@click="remove_gpio('input', item.bcm_id)"
>
mdi-trash-can-outline
Rimuovi
</v-btn>
</template>
.
<!– v-on:pull-change=”pullChange” –>
<td :colspan="”headers.length”">
<gpioInputDetailRow
:rowData="item"
v-on:pull-change="pullChange"
v-on:debounce-change="debounceChange"
>.
</td>
</template>
</v-data-table>
Come potete vedere ho avvolto un altro componente per lo slot expanded-item. Questo componente è irrilevante per la nostra discussione attuale, quindi non fornisco il codice per esso.
Ho evidenziato le parti importanti qui sopra.
Questi sono:
- :items="gpioInputTableData" - questo collega i dati alla chiave items della tabella dati Vuetify
- item-key="bcm_id" - questo è importante per dare una chiave unica per ogni voce dei vostri dati (che è data come un array agli elementi).
- se ometti di impostare questo, tutte le tue righe di dettaglio si apriranno e chiuderanno in una volta sola.
- il valore dovrebbe essere unico come discusso; nel caso in cui i tuoi dati abbiano potenzialmente valori duplicati in tutte le chiavi, devi creare un'ulteriore chiave unica
- mostra-espandi - questo mostrerà gli Chevron
- :expanded.sync="gpioInputTableExpanded" - notate l'uso del modificatore sync, per sincronizzare i cambiamenti indietro! Questa è una variabile in cui memorizzare gli elementi attualmente espansi.
poi:
- @click.ctrl.exact="configGpioAll('input', item)" - come potete vedere, su Ctrl + Click, sto chiamando una funzione di utilità per alternare tutti gli slot di espansione, a seconda dello stato dell'elemento corrente. Passo l'elemento ad essa, che deve essere espanso
- @click.exact="configGpio('input', item)" - come vedete, su un clic esatto, chiamo un'altra funzione di utilità (ci arriveremo tra poco), passando anche l'elemento corrente
finalmente:
- . - questo Slot contiene l'elemento espanso. Il passaggio delle intestazioni è importante:
- <td :colspan="”headers.length”"> - ... perché permette di creare una cella che abbraccia tutte le colonne
Ecco come appare il mio data() (estratto):
dati () {
ritorno {
caricamento: vero,
gpioInputTableData: [],
gpioInputTableHeaders: [
{ testo: 'Nome', valore: 'nome'},
{ testo: 'Valore', valore: 'valore'},
{ testo: 'Azione', valore: 'azione'}
],
gpioInputTableExpanded: []}
},
Ed ecco le due funzioni di utilità:
configGpioAll: function (source, item){
var ref = null;
var refTable = null;
se (source === 'input'){
ref = 'gpioInputTableExpanded';
refTable = 'gpioInputTableData';
} else if (source === 'output'){
ref = 'gpioOutputTableExpanded';
refTable = 'gpioOutputTableData';
} else if (source === 'softpwm'){
ref = 'gpioSoftPWMTableExpanded';
refTable = 'gpioSoftPWMTableData';
}
// abbiamo una corrispondenza per questo articolo (è aperto?)
se (this[ref].filter(e => e.bcm_id === item.bcm_id).length > 0){
// rimuovi tutti gli elementi
console.log("configGpioAll: removing");
questo[ref] = [];
}
else {
console.log("configGpioAll: adding");
// aggiungere tutti gli elementi
this[ref] = this[refTable];
}
},
in configGpioAll, controllo se ho la tabella input, output o softpwm (per evitare di duplicare il codice), e imposto i riferimenti alla variabile estesa appropriata (vedi dati sopra), e i dati della tabella stessa.
Se l'elemento è contenuto all'interno dei dati espansi (io abbino per la mia chiave unica, bcm_id), chiudo tutti gli elementi espansi - per questo ho semplicemente impostato la variabile espansa su un array vuoto.
Se l'elemento NON è contenuto nei dati espansi, apro tutti gli elementi, mettendo tutti i dati della tabella.
Nota: potrebbe valere la pena di sperimentare se un array di oggetti contenenti solo le chiavi uniche potrebbe essere sufficiente per far funzionare anche questo.
configGpio: function (source, item){
var ref = null;
se (source === 'input'){
ref = 'gpioInputTableExpanded';
} else if (source === 'output'){
ref = 'gpioOutputTableExpanded';
} else if (source === 'softpwm'){
ref = 'gpioSoftPWMTableExpanded';
}
se (this[ref].filter(e => e.bcm_id === item.bcm_id).length > 0){
// rimuovere l'elemento
this[ref] = this[ref].filter(e => e.bcm_id !== item.bcm_id);
}
else {
// aggiungere l'elemento
this[ref].push(item);
}
},
in configGpio, faccio cose simili - ma invece di rimuovere tutti gli elementi, filtro e rimuovo l'elemento che corrisponde al bcm_id che mi è stato passato.
Se l'elemento non è presente, lo spingo nella variabile espansa.
Questo è il motivo per cui ho bisogno dell'intero elemento, non solo del bcm_id. Ho scelto di avere simmetria nel mio codice, quindi configGpioAll che tecnicamente ha bisogno solo del bcm_id ottiene anche l'intero elemento.