我是Vue的新手,所以对我很轻松!这是情况。必须有比我在这里做的更好的方式。
我有一个简单的2列HTML表格:
<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>
我想更新“应用程序分配计数”列(但仅针对某些行),这由AJAX调用的结果确定。因此,假设表有10行,AJAX调用可能会说第1,4和7行的“应用程序分配计数”列的值需要更新,例如,分别为247,80和356。我正在考虑使用像这样的JSON对象作为我的Vue数据对象,因为AJAX响应看起来像这样。
data: {
num_of_applications_assigned: [
{
"party_id": "1",
"num": "247"},
{
"party_id": "4",
"num": "80"},
{
"party_id": "7",
"num": "356"}
]
},
我认为可能有办法将“应用程序分配的计数”列绑定到由AJAX调用更新的Vue数据对象,但除了添加唯一的v-之外,我没有看到这样做的方法。文本到每个单独的<TD>
单元格,例如
<div v-text="num_of_applications_assigned_1"></div>
<div v-text="num_of_applications_assigned_2"></div>
etc
然而,这导致我在用AJAX响应的结果更新这些v文本时编写一些非常复杂的代码,因为我必须动态构造引用:
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 + ';');
}
});
是的,我知道 eval很糟糕 - 这就是我在这里寻求帮助的原因!什么是更好的方法,或者Vue不适合这种情况?
答案 0 :(得分:2)
我无法使用v-for,因为表及其行都是生成服务器端
如果你不能使用v-for
,你仍然可以使用Vue来渲染你的数据,如果你决定在服务器端做一些额外的工作,并且你的数据模型有点不同。它不如v-for
那么优雅,但它应该是直截了当的。
例如,如果您想创建一个双列表,其中Vue将呈现/更新第二列的单元格值,您可以在服务器端生成类似这样的内容:
<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>
您使用自己喜欢的服务器端语言动态生成值party_1
,party_2
,party_3
。
这意味着一个基础数据结构如下:
applications: {
party_1: { num: 1 },
party_2: { num: 2 }
}
在服务器端动态创建该结构应该很简单。然后,只需创建一个Vue实例并使用该数据结构填充其初始data
对象:
new Vue({
el: '#app',
data: {
applications: {
party_1: { num: 1 },
party_2: { num: 2 }
}
}
});
当HTML在浏览器中呈现时,Vue实例会挂载,它将从其data
对象更新绑定的单元格值。这些值是被动的,因此对Vue实例的基础数据的任何后续更改都将自动呈现。
希望这会有所帮助:)
答案 1 :(得分:1)
Vue中的想法是准备好所有数据,让Vue.JS进行渲染。因此,您的数据应该如下所示:
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 },
]
},
}
然后,你可以让Vue渲染它:
<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>
仍然是问题,如何更新它。获取新数据后,您必须修改数组this.assignedApplications
,然后Vue将正确地重新呈现表。如果您的行具有唯一ID,则可以使assignizedApplications而不是数组成为类似于地图的数据结构,因此您可以通过其id轻松访问特定行并更改值。如果没有,您必须在整个数组中搜索每个更改并进行调整:
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;
}
}
}
}
总之,一个例子看起来像这样:
<!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>
&#13;