Issue
Expectations:
The application should work as a socket, only data is received through periodic ajax requests to the server.
Problem:
When changing data on the "client (browser) No. 1", soon the data changes on the "client No. 2". BUT, if you now change the data on the "client number 2", then the changes on the "client number 1" does not occur.
Simply put, the data is not synchronized. The application does not notice changes in incoming data.
I can not understand the reason.
vuetest.php
<div id="app">
<table border="1">
<tr v-for="item in items">
<td>
<div @click="editCell"
@focusout="saveCell"
@keyup.enter="saveCell"
>{{item.value}}</div>
</td>
</tr>
</table>
</div>
vuetest.js
var app = new Vue({
el: '#app',
created() {
this.intervalTrigger();
this.fetchData();
},
data: {
"items":[]
},
methods: {
fetchData() {
if (this.intervalId === 0){
this.intervalTrigger();
}
var bodyFormData = new FormData();
bodyFormData.set('module', 'vueTest');
bodyFormData.set('command', 'getData');
axios({
method: 'post',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
url: '/vueajax.php',
data: bodyFormData
})
.then(response => {
this.items = response.data.items;
});
return;
},
sendAjax(data){
var bodyFormData = new FormData();
var answer;
$.each(data, function(i, obj) {
bodyFormData.set(''+ i +'', obj);
});
answer = axios({
method: 'post',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
url: '/vueajax.php',
data: bodyFormData
});
return answer;
},
intervalTrigger: function () {
this.intervalId = window.setInterval( function() {
app.fetchData()
}, 5000 );
return this.intervalId;
},
editCell: function(e){
if($(e.target).is('.bg-edit')) return;
$(e.target).attr('contenteditable', 'true');
$(e.target).addClass('bg-edit');
$(e.target).focus();
},
saveCell: function(e){
var value = $(e.target).text();
var answer;
$(e.target).html(value);
var data = {
'module': 'vueTest',
'command': 'setValue',
'value': value
};
answer = this.sendAjax(data);
answer.then(response => {
$(e.target).text(response.data.result);
});
$(e.target).removeAttr('contenteditable', 'true');
$(e.target).removeClass('bg-edit');
}
}
});
vueajax.php
<?php
if ($_POST['module'] === 'vueTest'){
if ($_POST['command'] == 'setValue'){
$new_value = (int) $_POST['value'];
file_put_contents("vuetest.txt", $new_value);
echo json_encode(["result" => $new_value]); die;
} else {
$value = (int) trim(file_get_contents("vuetest.txt"));
}
echo json_encode(
[
"items" => [
0 => ["value" => $value]
]
]
);
die;
Solution
Generally speaking, these issues are down to Vue's issues with reactivity and arrays: https://v2.vuejs.org/v2/guide/reactivity.html
With this in mind, you could try:
this.$set(this, 'items', response.data.items)
instead of this.items = response.data.items
This forces Vue to rebind that instance variable with the new items instead.
It's also worth noting, you need a key on your loop:
<tr v-for="item in items" :key="item.id">
- You'll likely have a console error stating the same.
Answered By - webnoob Answer Checked By - Pedro (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.