Vue - 如何将表列绑定到数据对象?
我是Vue的新手,对我来说很容易!这是情况。必须有比我在这里做的更好的方式。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">
\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>
我想更新“应用程序分配数”一栏(但仅限于某些行),由结果来决定的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"}
]
},
我认为有可能是绑定的“应用程序分配count”列到被通过AJAX调用更新Vue的数据对象的方式,但我不明白的方式做多增加这个其他一个独特的v-文本给每个人单元例如
<div v-text="num_of_applications_assigned_1"></div>
<div v-text="num_of_applications_assigned_2"></div>
etc
然而,这导致我写更新这些V-文本与AJAX响应的结果时,一些很费解的代码,因为我必须动态地构建引用:
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不适合这种情况?
我不能使用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实例的底层数据的任何后续更改都会自动呈现。
希望这有助于:)
谢谢!这就是我一直在寻找的! –
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,你可以让assignApplications而不是一个数组类似地图的数据结构,所以你可以很容易地通过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">
\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>
谢谢你的详细答案,我真的很感激。不幸的是,我真的认为我不能使用v-for,因为表和它的行都是生成服务器端的(我将使用的实际表比这个例子复杂得多)。正如我在我的问题中所说的,我真的认为Vue不适合我的情况。我可能不得不依靠jQuery来更新这些列值。 –
使用v-的指令,是的VUE是被动的,所有你需要做的是从Ajax调用和表格将与更新重新解析结果更新数据。 –
在这种情况下,我不认为我可以使用v-for,因为表格行是在服务器上预先创建的。我可以添加东西到单独的行或单元格。你有什么建议? –