Vue - how to bind table column to a data object? Vue - how to bind table column to a data object? vue.js vue.js

Vue - how to bind table column to a data object?


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 :)


The idea in Vue is to have all your data ready, and let Vue.JS do the rendering. So, your data should probably look like this:

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 },   ]  },}

Then, you can let Vue render it:

<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>

Remains the problem, how to update it. After getting the new data, you have to modify the array this.assignedApplications, and then Vue will re-render the table correctly. If your rows have a unique id, you could make assignedApplications instead of an array a map-like data structure, so you can easy access specific rows by their id and change the value. If not, you have to search through the whole array for every change and adapt it:

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;            }        }    }}

All together, an example could look like this:

<!DOCTYPE html><html><head>  <script src="https://unpkg.com/vue"></script></head><body>  <div id="app">  	<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>		<a href="#" v-on:click.prevent="update">Update</a>	</div>  <script>    var app = new Vue({      el: '#app',      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 },        ]      },      methods: {      	update: function() {      		let newData = [      			{ party_id: 1, num: 243},      			{ party_id: 2, num: 80},      			{ party_id: 4, num: 0},      		];      		this.mergeInNewData(newData);      	},      	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;      				}      			}      		}      	}      }    })  </script></body></html>