2017-10-20 2 views
2

Ich bin neu in Vue, also geh einfach zu mir! Hier ist die Situation. Es muss einen besseren Weg geben als das, was ich hier mache.Vue - Wie bindet man Tabellenspalten an ein Datenobjekt?

Ich habe eine einfache 2-Säule HTML-Tabelle:

<table id="contacts"> 
 
<tbody> 
 
    <tr> 
 
     <th class="column-1"> 
 
      Contact Id 
 
     </th> 
 
     <th class="column-2"> 
 
      Applications assigned count 
 
     </th>  
 
    </tr> 
 
     <tr class="odd" id="contacts_tr_1"> 
 
\t <td class="column-1"> 
 
     1 
 
     </td> 
 
\t <td class="column-2"> 
 
     247 
 
     </tr> 
 
     <tr class="even last" id="contacts_tr_2"> 
 
\t <td class="column-1"> 
 
     2 
 
     </td> 
 
\t <td class="column-2"> 
 
    0 
 
     </td> 
 
    </tr> 
 
     <tr class="even last" id="contacts_tr_2"> 
 
\t <td class="column-1"> 
 
     3 
 
     </td> 
 
\t <td class="column-2"> 
 
    44 
 
     </td> 
 
    </tr> 
 
     <tr class="even last" id="contacts_tr_2"> 
 
\t <td class="column-1"> 
 
     ......... 
 
     </td> 
 
\t <td class="column-2"> 
 
    ......... 
 
     </td> 
 
    </tr> 
 

 
     <tr class="even last" id="contacts_tr_2"> 
 
\t <td class="column-1"> 
 
     10 
 
     </td> 
 
\t <td class="column-2"> 
 
    76 
 
     </td> 
 
    </tr> 
 
</tbody> 
 
</table>

Ich mag die „Anwendungen zugewiesen count“ Spalte (aber nur für bestimmte Zeilen) aktualisieren, wie durch das Ergebnis bestimmt eines AJAX-Anrufs. Unter der Annahme, dass die Tabelle 10 Zeilen aufweist, könnte der AJAX-Aufruf also sagen, dass der Wert der Spalte "Anzahl der zugewiesenen Anwendungen" der Zeilen 1, 4 und 7 aktualisiert werden muss, z. 247, 80 und 356 jeweils. Ich denke darüber nach, ein JSON-Objekt wie dieses als mein Vue-Datenobjekt zu verwenden, weil die AJAX-Antwort so aussehen wird.

data: { 
    num_of_applications_assigned: [ 
     { 
      "party_id": "1", 
      "num": "247"}, 
     { 
      "party_id": "4", 
      "num": "80"}, 
     { 
      "party_id": "7", 
      "num": "356"} 

    ] 
    }, 

Ich dachte, es könnte ein Weg sein, um die „Anwendungen zugewiesen count“ Spalte auf das Vue Datenobjekt zu binden, die durch den AJAX-Aufruf aktualisiert wird, aber ich sehe keinen Weg, diese andere zu tun, als das Hinzufügen ein eindeutiger v-Text zu jeder einzelnen Zelle <TD> z

<div v-text="num_of_applications_assigned_1"></div> 
<div v-text="num_of_applications_assigned_2"></div> 
etc 

Dies hat jedoch mich führen einige sehr gewundenen Code zu schreiben, wenn diese v-Texte mit den Ergebnissen der AJAX-Antwort zu aktualisieren, wie ich, um dynamisch die Referenzen konstruieren:

let vm = this; 
    jQuery.ajax({ 
      url: myurl 
     }).then(function(response) {     
      for (var i = 0, len = vm.num_of_applications_assigned.length; i < len; i++) { 
      var party_id = vm.num_of_applications_assigned[i].party_id; 
      var dref = 'vm.num_of_applications_assigned_'+party_id; 
      var dnum = vm.num_of_applications_assigned[i].num; 
      eval(dref + ' = ' + dnum + ';'); 
      }   
    }); 

Ja Ich weiß, Eval ist schlecht - deshalb bin ich hier um Hilfe bitten! Was ist ein besserer Weg dies zu tun, oder passt Vue nicht gut zu dieser Situation?

+1

Verwenden Sie v-for-Richtlinie und ja vue reaktiv ist, alles, was Sie tun müssen, haben Ihre Daten mit den Ergebnissen aus dem Ajax-Aufruf aktualisiert und die Tabelle würde mit dem Updates rerender. –

+0

Ich glaube nicht, dass ich in diesem Fall v-for verwenden kann, da die Tabellenzeilen auf dem Server vordefiniert sind. Ich kann jedoch einzelne Zeilen oder Zellen hinzufügen. Was schlägst du vor? –

Antwort

2

Ich kann v-for nicht verwenden, da die Tabelle und ihre Zeilen alle serverseitig

generiert werden

Wenn Sie v-for nicht verwenden können, können Sie Vue weiterhin verwenden, um Ihre Daten zu rendern, wenn Sie sich für zusätzliche Arbeiten auf der Serverseite entscheiden und Ihre Daten ein wenig anders gestalten. Es ist weniger elegant als v-for, aber es sollte einfach sein.

<table id="app"> 
    <tr> 
     <td>1</td> 
     <td>{{ applications.party_1.num }}</td> 
    </tr> 
    <tr> 
     <td>2</td> 
     <td>{{ applications.party_2.num }}</td> 
    </tr> 
</table> 

Wo Sie verwenden:

Zum Beispiel, wenn Sie eine zweispaltige Tabelle erstellen wollen, wo Vue würde die zweite Spalte der Zelle Wert machen/aktualisieren, können Sie so etwas wie dies auf der Server-Seite erzeugen Ihre bevorzugte serverseitige Sprache, um Werte party_1, party_2, party_3 dynamisch zu generieren.

bedeutet dies, dass eine zugrunde liegende Datenstruktur wie folgt:

applications: { 
    party_1: { num: 1 }, 
    party_2: { num: 2 } 
} 

Diese einfach sein soll, dass die Struktur dynamisch auf der Server-Seite zu erstellen. Dann erstellen Sie einfach eine Vue-Instanz und bevölkert sein anfängliches data Objekt mit dieser Datenstruktur:

new Vue({ 
    el: '#app', 
    data: { 
    applications: { 
     party_1: { num: 1 }, 
     party_2: { num: 2 } 
    } 
    } 
}); 

Wenn der HTML-Code in einem Browser dargestellt wird, das Vue Instanz Halterungen und es wird die gebundenen Zellwerte von seinem data Objekt aktualisieren . Diese Werte sind reaktiv, sodass alle nachfolgenden Änderungen an den zugrunde liegenden Daten der Vue-Instanz automatisch gerendert werden.

this helps :)

+0

Danke! Das habe ich gesucht! –

1

Die Idee in Vue ist, alle Ihre Daten bereit zu haben, und Vue.JS das Rendering durchführen zu lassen. Also, Ihre Daten wahrscheinlich sollte wie folgt aussehen:

data: { 
    assignedApplications: [ 
    { party_id: 1, num: 247 }, 
    { party_id: 2, num: 0 }, 
    { party_id: 3, num: 44 }, 
    { party_id: 4, num: 76 }, 
    { party_id: 5, num: 9 }, 
    ] 
    }, 
} 

Dann können Sie lassen Vue es machen:

<table> 
    <tr> 
     <th class="column-1">Contact Id</th> 
     <th class="column-2">Applications assigned count</th>  
    </tr> 
    <tr v-for="a in assignedApplications"> 
     <td>{{a.party_id}}</td> 
     <td>{{a.num}}</td> 
    </tr> 
</table> 

bleibt das Problem, wie es zu aktualisieren. Nachdem Sie die neuen Daten erhalten haben, müssen Sie das Array this.assignedApplications ändern, und dann wird die Tabelle von Vue erneut gerendert. Wenn Ihre Zeilen eine eindeutige ID haben, können Sie zugewiesenen Anwendungen anstelle eines Arrays eine kartenähnliche Datenstruktur zuweisen, sodass Sie einfach auf bestimmte Zeilen anhand ihrer ID zugreifen und den Wert ändern können. Wenn nicht, müssen Sie für jede Änderung durch das gesamte Array suchen und anpassen:

mergeInNewData(newData) { 
    for (let i = 0; i < newData.length; i++) { 
     let changedData = newData[i]; 
     for (let j = 0; j < this.assignedApplications.length; j++) { 
      if (this.assignedApplications[j].party_id === changedData.party_id) { 
       this.assignedApplications[j].num = changedData.num; 
      } 
     } 
    } 
} 

Alle zusammen, könnte ein Beispiel wie folgt aussehen:

<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <script src="https://unpkg.com/vue"></script> 
 
</head> 
 
<body> 
 
    <div id="app"> 
 
    \t <table> 
 
\t \t \t <tr> 
 
\t \t \t \t <th class="column-1">Contact Id</th> 
 
\t \t \t \t <th class="column-2">Applications assigned count</th>  
 
\t \t \t </tr> 
 
\t \t \t <tr v-for="a in assignedApplications"> 
 
\t \t \t \t <td>{{a.party_id}}</td> 
 
\t \t \t \t <td>{{a.num}}</td> 
 
\t \t \t </tr> 
 
\t \t </table> 
 
\t \t <a href="#" v-on:click.prevent="update">Update</a> 
 
\t </div> 
 

 
    <script> 
 
    var app = new Vue({ 
 
     el: '#app', 
 
     data: { 
 
     assignedApplications: [ 
 
     \t { party_id: 1, num: 247 }, 
 
     \t { party_id: 2, num: 0 }, 
 
     \t { party_id: 3, num: 44 }, 
 
     \t { party_id: 4, num: 76 }, 
 
     \t { party_id: 5, num: 9 }, 
 
     ] 
 
     }, 
 
     methods: { 
 
     \t update: function() { 
 
     \t \t let newData = [ 
 
     \t \t \t { party_id: 1, num: 243}, 
 
     \t \t \t { party_id: 2, num: 80}, 
 
     \t \t \t { party_id: 4, num: 0}, 
 
     \t \t ]; 
 
     \t \t this.mergeInNewData(newData); 
 
     \t }, 
 
     \t mergeInNewData(newData) { 
 
     \t \t for (let i = 0; i < newData.length; i++) { 
 
     \t \t \t let changedData = newData[i]; 
 
     \t \t \t for (let j = 0; j < this.assignedApplications.length; j++) { 
 
     \t \t \t \t if (this.assignedApplications[j].party_id === changedData.party_id) { 
 
     \t \t \t \t \t this.assignedApplications[j].num = changedData.num; 
 
     \t \t \t \t } 
 
     \t \t \t } 
 
     \t \t } 
 
     \t } 
 
     } 
 
    }) 
 
    </script> 
 
</body> 
 
</html>

+0

Vielen Dank für die ausführliche Antwort, ich weiß es wirklich zu schätzen. Unglücklicherweise glaube ich wirklich, dass ich v-for nicht verwenden kann, da die Tabelle und ihre Zeilen alle serverseitig generiert werden (die tatsächliche Tabelle, die ich verwenden werde, ist viel komplexer als dieses Beispiel). Wie ich in meiner Frage gesagt habe, denke ich wirklich, dass Vue für meine Situation nicht gut ist. Ich muss möglicherweise auf jQuery zurückgreifen, um diese Spaltenwerte zu aktualisieren. –

Verwandte Themen