2017-10-20 64 views
2

我是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不适合这种情况?

+1

使用v-的指令,是的VUE是被动的,所有你需要做的是从Ajax调用和表格将与更新重新解析结果更新数据。 –

+0

在这种情况下,我不认为我可以使用v-for,因为表格行是在服务器上预先创建的。我可以添加东西到单独的行或单元格。你有什么建议? –

回答

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实例的底层数据的任何后续更改都会自动呈现。

希望这有助于:)

+0

谢谢!这就是我一直在寻找的! –

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,你可以让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>

+0

谢谢你的详细答案,我真的很感激。不幸的是,我真的认为我不能使用v-for,因为表和它的行都是生成服务器端的(我将使用的实际表比这个例子复杂得多)。正如我在我的问题中所说的,我真的认为Vue不适合我的情况。我可能不得不依靠jQuery来更新这些列值。 –

相关问题