2017-08-17 2 views
0

Ich muss die Daten von der Websocket-Verbindung empfangen verarbeiten. Im Datenmodell muss ich 2 Timer ausführen, um die Verbindungszeit zu zählen. Im Folgenden ist ein Beispiel für meine Implementierung:Ich kann setInterval nicht in vuejs ausführen

var socket = io.connect('http://localhost:3000'); 

window.onload = function() { 

    var vm = new Vue({ 
     el: '#indication', 
     data: { 
      incomingData: [] 
     }, 
     methods: { 
      updateB: function (i, num) { 
       this.incomingData[i].b_number += " (" + num + ")"; 
      }, 
      updateWaitTime: function (i) { 
       ++this.incomingData[i].wait_time; 
      }, 
      updateTalkTime: function (i) { 
       ++this.incomingData[i].talk_time; 
      } 
     } 
    }); 

    socket.on("message", function (msg) { 
     message = JSON.parse(msg); 
     console.log(message) 
     if (message.status === "NewChannel") { 
      var now = new Date() 
      var pos = vm.incomingData.push({ 
       id: message.id, count_of_day: ++counter, 
       a_number: message.callernum, b_number: message.number, date: now.toLocaleString(), talk_time: 0, wait_time: 0 
      }); 
      for (var i = 0; i < vm.incomingData.length; i++) { 
       if (vm.incomingData[i].id === message.id) { 
        console.log("start NCTimer for " + message.id); 
        timersNC[message.id] = setInterval(function() { 
         vm.updateWaitTime(i); 
        }, 1000); 
        break; 
       } 
      } 
      return false; 
     } else if (message.status === "bridge") { 
      for (var i = 0; i < vm.incomingData.length; i++) { 
       if (vm.incomingData[i].id === message.id) { 
        console.log("bridge for " + message.id); 
        vm.updateB(i, message.operator_ext); 
        console.log("STOPPING TALT_TIME HERE"); 
        clearInterval(timersNC[message.id]); 
        delete timersNC[message.id]; 
        break; 
       } 
      } 
      return false; 
     } 

     else if (message.status === "hangup") { 
      for (var i = 0; i < vm.incomingData.length; i++) { 
       if (vm.incomingData[i].id === message.id) { 
        for (var id in timersNC){ 
         if (id === message.id){ 
          clearInterval(timersNC[message.id]); 
          delete timersNC[message.id]; 
          console.log("DELETED NC FROM HANGUP!!!!") 
          break; 
         } 
        } 
        for (var id in timersBR){ 
         if (id === message.id){ 
          clearInterval(timersBR[message.id]); 
          delete timersBR[message.id]; 
          console.log("DELETED BR FROM HANGUP!!!!") 
          break; 
         } 
        } 
        console.log("hangup for " + message.id); 
        vm.incomingData.splice(i, 1); 
        break; 
       } 
      } 
      return false; 
     } 
     else return; 
    }) 
}; 

Die Daten werden in der folgenden Tabelle aktualisiert:

<div id="indication"> 
     <table class="rtable"> 
      <thead> 
       <tr> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
        <th>...</th> 
       </tr> 
      </thead> 

      <tbody id="dynamic_row"> 
       <tr v-for="d in incomingData" :key='d.id'> 
        <td>{{d.b_number}}</td> 
        <td>{{d.queue_number}}</td> 
        <td>{{d.count_of_day}}</td> 
        <td>{{d.date}}</td> 
        <td>{{d.a_number}}</td> 
        <td>{{d.mobile_operator}}</td> 
        <td>{{d.status}}</td> 
        <td>{{d.category}}</td> 
        <td>{{d.wait_time}}</td> 
        <td>{{d.talk_time}}</td> 
       </tr> 
      </tbody> 
     </table> 
    </div> 

Diese Schaltung arbeitet bis zu einem bestimmten Punkt, wenn der folgende Fehler auftritt:

index.js:62 Uncaught TypeError: Cannot read property 'wait_time' of undefined 
    at Vue$3.updateWaitTime (index.js:62) 
    at Vue$3.boundFn [as updateWaitTime] ([email protected]:188) 
    at index.js:83 

Ich verstehe nicht, warum das passiert und wie es funktioniert. Ich entschuldige mich im Voraus, wenn der Fehler dumm ist, ich bin ein absoluter Anfänger in Vuejs. Ich verstehe, dass das Problem in den asynchronen Löschen und Hinzufügen von Elementen ist, aber ich weiß nicht, wie es zu lösen

Antwort

0

Es ist, weil die for Schleife bereits durch die Zeit, die setInterval() Rückrufe laufen beendet hat. Das bedeutet, dass i auf den gleichen Wert wie vm.incomingData.length erhöht wurde, bis vm.updateWaitTime(i) ausgeführt wird und i dann auf ein nicht vorhandenes Element im Array zeigt.

Was Sie tun müssen, ist der Geltungsbereich i zu jeder Iteration. Wenn Sie in der Lage sind ES6 Syntax verwenden Sie können dies tun, indem Sie Ihre for Schleife wie folgt zu schreiben:

for (let i = 0; i < vm.incomingData.length; i++) { 

D.h. unter Verwendung von let anstelle von var. Wenn ES6 keine Option ist, müssen Sie innerhalb jeder Iteration einen neuen Funktionsbereich erstellen, der eine Bereichskopie von i erstellt.

timersNC[message.id] = setInterval((function (idx) { 
        return function() { 
         vm.updateWaitTime(idx); 
        }; 
       }(i)), 1000); 

... oder alternativ: Dies kann durch das Schreiben der setInterval() Ausdruck wie dies erreicht werden

timersNC[message.id] = setInterval((function (idx) { 
        vm.updateWaitTime(idx); 
       }).bind(null, i), 1000); 
+0

Danke für die Erklärung, jetzt verstehe ich, was der Fehler ist, aber leider nicht eine der vorgeschlagene Methoden könnten mein Problem lösen –