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:

immagine

facendo clic sul chevron o sul pulsante di configurazione si aprirà la riga di dettaglio:

immagine

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 immagine
  • :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à:

immagine

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.

immagine

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.