2017-10-20 67 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來更新這些列值。 –

相關問題