Обновление объекта с набором vue не изменяется в html в слушателе socketio - PullRequest
0 голосов
/ 23 октября 2018

У меня есть приложение чата с vue for front, где я слушаю трансляцию с laravel.

У меня есть объект данных для сообщений, которые я обновляю новыми сообщениями, когда чат активен.

Вот обновление с использованным кодом:

data() {
   return {
    msg: '',
    chatlist: JSON.parse(this.chatusers),
     activeChats: [],
    chatData: {},
    openedChats: [],
    maxOpened: Math.floor(window.innerWidth / 320),
   }
},

methods: {
listener() {
    Echo.private('user.' + window.uid)
                .listen('Chat', (e) => {
        //first if is for active and opened chats and here reactivity doesnt work
        if (this.activeChats.includes(e.data.user.id) && this.openedChats.includes(e.data.user.id)) {
        this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1 , e.data.message);
        setTimeout(function() {
                let chat = document.getElementById('chat-'+e.data.user.id);
                chat.scrollTop = chat.scrollHeight;
            }, 100);
        //second if is for inactive chats and here reactivity works
        }else if (!this.activeChats.includes(e.data.user.id)) {
            axios.post('/messages', {
                id: e.data.user.id
            }).then((res) => {
                this.chatData[e.data.user.id] = res.data;
                this.activeChats.push(e.data.user.id);
                setTimeout(function() {
                    let chat = document.getElementById('chat-'+e.data.user.id);
                    chat.scrollTop = chat.scrollHeight;
                }, 100);
            }).catch((err) => {
                console.log(err);
            });
        //third if is for active chats that are not opened on page, so its same as first and it does not work
        }else if(this.activeChats.includes(e.data.user.id) && !this.openedChats.includes(e.data.user.id) && this.openedChats.length < this.maxOpened) {
            this.openedChats.push(e.data.user.id);
            this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1, e.data.message);
        }

    });
}
}

Я звоню слушателю в mounted.

Объекты меняются, но на стороне, которая принимает сообщение, нет реактивности, поэтомупроблема может быть в прослушивании эха, но, поскольку в течение секунды, если оператор работает, я не уверен, в чем может быть проблема ...

Похоже, установка свойства объекта из прослушивания эха не вызывает изменения ..

Обновление:

Я попробовал это:

Я открыл чат при клике, который заполнил chatData [e.data.user.id] так же, как я использую, когда я получаю новое сообщение и чатне открывается .. Затем:

listener() {
    Echo.private('user.' + window.uid)
                .listen('Chat', (e) => {
this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1 , e.data.message);
});
}

Я называю это, и оно все еще не работает, а это означает, что, если он работает из-за эхо-сигнала Laravel, но не внутри, должна быть проблема.

Итак, я попытался найти проблему и увидел, чтоjects обновляются, но не вызывают изменения.

Я нашел глупое решение добавить новую переменную в виде пустого массива, который обновляется в то же время и в месте, где я обновляю объект, например так:

this.$set(this.chatData[e.data.user.id].messages, e.data.message.id - 1 , e.data.message);
this.array.push(1);

И затем я использовал этот массив в v-for рядом с v-for, который использует объект.

Эта часть важна, поэтому она также вызывает изменение объекта, почему я не знаю, но это работает: D

1 Ответ

0 голосов
/ 24 октября 2018

Ваша проблема фактически создается второй частью кода:

    //second if is for inactive chats and here reactivity works
    }else if (!this.activeChats.includes(e.data.user.id)) {
        axios.post('/messages', {
            id: e.data.user.id
        }).then((res) => {
            this.chatData[e.data.user.id] = res.data;
            this.activeChats.push(e.data.user.id);
            setTimeout(function() {
                let chat = document.getElementById('chat-'+e.data.user.id);
                chat.scrollTop = chat.scrollHeight;
            }, 100);
        }).catch((err) => {
            console.log(err);
        });

В основном строка:

this.chatData[e.data.user.id] = res.data;

Это добавление нового свойства к this.chatData без прохождения его через Vue.set, что означает, что, пока вы хорошо его читаете, любые изменения этого объекта не отслеживаются.

Что внутри данных, которыедолжен отслеживаться? data.messages

Поскольку это свойство не отслеживается, любое взаимодействие с ним не приведет к правильной "реактивности" и требует

Исправлениеесли ваша проблема проста, убедитесь, что новые записи в структуре chatData передаются через функцию набора Vue:

this.$set(this.chatData, e.data.user.id, res.data);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...