I'm new to Vue, so go easy on me! Here's the situation. There must be a better way than what I'm doing here.
I have a simple 2 column HTML table:
<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">
<td class="column-1">
1
</td>
<td class="column-2">
247
</tr>
<tr class="even last" id="contacts_tr_2">
<td class="column-1">
2
</td>
<td class="column-2">
0
</td>
</tr>
<tr class="even last" id="contacts_tr_2">
<td class="column-1">
3
</td>
<td class="column-2">
44
</td>
</tr>
<tr class="even last" id="contacts_tr_2">
<td class="column-1">
.........
</td>
<td class="column-2">
.........
</td>
</tr>
<tr class="even last" id="contacts_tr_2">
<td class="column-1">
10
</td>
<td class="column-2">
76
</td>
</tr>
</tbody>
</table>
I want to update the "Applications assigned count" column (but only for certain rows), as determined by the result of an AJAX call. So assuming the table has 10 rows, the AJAX call might say that the value of the "Applications assigned count" column of rows 1, 4 and 7 need to be updated, to e.g. 247, 80 and 356 respectively. I'm thinking of using a JSON object like this as my Vue data object, because the AJAX response will look like this.
data: {
num_of_applications_assigned: [
{
"party_id": "1",
"num": "247"},
{
"party_id": "4",
"num": "80"},
{
"party_id": "7",
"num": "356"}
]
},
I thought there might be a way to bind the "Applications assigned count" column to the Vue data object that gets updated by the AJAX call, but I don't see a way to do this other than adding a unique v-text to each individual <TD> cell e.g.
<div v-text="num_of_applications_assigned_1"></div>
<div v-text="num_of_applications_assigned_2"></div>
etc
However, this has lead me to writing some very convoluted code when updating those v-texts with the results of the AJAX response, as I have to dynamically construct the references:
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 + ';');
}
});
Yes, I know eval is bad - that's why I'm here asking for help! What is a better way of doing this, or is Vue not a good match for this situation?
I can't use v-for, as the table and its rows are all generated server side
If you cannot use v-for you can still use Vue to render your data, if you decide to do some additional work on the server-side, and you mould your data a little differently. It's less elegant than v-for but it should be straightforward.
For example, if you wanted to create a two-column table where Vue would render/update the second column's cell values, you could generate something like this on the server side:
<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>
Where you use your favourite server-side language to generate values party_1, party_2, party_3 dynamically.
This implies that an underlying data structure like so:
applications: {
party_1: { num: 1 },
party_2: { num: 2 }
}
This should be straightforward to create that structure dynamically on the server-side. Then, just create a Vue instance and populate its initial data object with that data structure:
new Vue({
el: '#app',
data: {
applications: {
party_1: { num: 1 },
party_2: { num: 2 }
}
}
});
When the HTML is rendered in a browser, the Vue instance mounts and it will update the bound cell values from its data object. These values are reactive, so any subsequent changes to the Vue instance's underlying data will be rendered automatically.
Hope this helps :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With