2016-05-13 38 views
8

Desidero aggiornare la mia area di disegno su ogni richiesta AJAX se viene trovato un nuovo utente o vi è una nuova connessione di utenti esistenti.Aggiorna tag canvas HTML su ogni richiesta AJAX con nuovi dati

Ho utenti e le connessioni tra di loro:

var data=[ 
      { 
       "Id": 38, 
       "Connections":[39,40], 
       "Name":"ABc" 
      }, 
      { 
       "Id": 39, 
       "Connections":[40], 
       "Name":"pqr" 
      }, 
      { 
       "Id": 40, 
       "Connections":[], 
       "Name":"lmn" 
      }] 

Nel all'utente nell'esempio precedente, con Id:38 è collegato a user 39 and 40 e user 39 is connected to user 40 and user 40 è già collegato alla user 39 and user 38 so user 40 Connection array is blank.

Ho un servizio Web che verrà attivato ogni 1-2 secondi per visualizzare gli utenti appena iscritti in questa pagina e una nuova connessione tra gli utenti esistenti che ho memorizzato nella mia tabella e questo servizio Web recupererà tutti gli utenti insieme al loro connessioni.

Quindi all'inizio la mia pagina verrà caricata ma dopo di allora la mia pagina non si aggiornerà e nuovi utenti dovrebbero essere visualizzati e le nuove connessioni dovrebbero essere connesse con la chiamata AJAX al mio servizio web.

Ma con una richiesta Ajax tutto viene incasinato. Questo è un JSBin I have created.

uscita sto ottenendo:

enter image description here

Ho appena 4 utenti e 3 attacchi, come si può vedere nel mio uscita JSBin allora dovrebbe essere solo 4 rettangoli e io non sono l'aggiunta di più utenti, ma ancora ottenendo questo output disordinato. Codice

Fonte di riferimento: Reference Fiddle

Sto cercando di ottenere il risultato come indicato in precedenza il violino, ma non sempre.

output previsto: 4 rettangoli con animazioni

Aggiornato Js bin Demo: Updated JSBin

Con sopra aggiornato JSBin sto ottenendo questa uscita, ma non sono in movimento (animazione non funziona):

Updated Output

+1

Stai cancellando la tela tra i disegni? Quell'output sembra quello che otterresti dai rettangoli che persistono tra ogni aggiornamento. – DBS

+0

@DBS è possibile elaborare –

+1

Quando si disegna qualcosa su una tela, l'immagine precedente rimane visibile a meno che non si rimuova la tela manualmente. Quindi il disegno di uno dei tuoi ID più volte può apparire come più quadrati. Pensa ad aggiungere nuovi quadrati alla stessa immagine, invece di creare una nuova immagine. Prova a schiarirlo una volta ottenuta la richiesta Ajax, prima di disegnare nuovi quadrati. – DBS

risposta

5

le scatole non si muovono perché il codice fo il loro spostamento non viene mai chiamato.

Se si sposta la parte che anima le caselle da updateUsers() al ciclo dell'animazione principale, esse si animeranno.

Spostare la sezione da questa parte:

function updateUsers() { 
    fetchData(); 

    // this part ------------------------------------------------------ 
    $.each(users, function(index, user) { 
    if (user.x <= 0) user.dir.x = 1; 
    if (user.x + user.width > canvas.width) user.dir.x = -1; 
    if (user.y <= 0) user.dir.y = 1; 
    if (user.y + user.height > canvas.height) user.dir.y = -1; 

    user.x += user.dir.x; 
    user.y += user.dir.y; 
    }); 
    // to here -------------------------------------------------------- 

    //window.setTimeout(updateUsers, 1000/60); 
    window.setTimeout(updateUsers, 9000); 
} 

a qui:

function drawUsers() { 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
    $.each(users, function(index, user) { 
    ctx.beginPath(); 
    ctx.rect(user.x, user.y, user.width, user.height); 
    ctx.strokeStyle = 'red'; 
    ctx.stroke(); 

    if (user.connections != null) { 
     user.connections.forEach(function(id) { 
     const other = users.find(user => user.id === id); 

     ctx.beginPath(); 
     ctx.moveTo(user.x + (user.width/2), user.y + (user.height/2)); 
     ctx.lineTo(other.x + (other.width/2), other.y + (other.height/2)); 
     ctx.strokeStyle = 'black'; 
     ctx.stroke(); 
     }); 
    } 
    }); 

    // animate here 
    $.each(users, function(index, user) { 
    if (user.x <= 0) user.dir.x = 1; 
    if (user.x + user.width > canvas.width) user.dir.x = -1; 
    if (user.y <= 0) user.dir.y = 1; 
    if (user.y + user.height > canvas.height) user.dir.y = -1; 

    user.x += user.dir.x; 
    user.y += user.dir.y; 
    }); 
    window.requestAnimationFrame(drawUsers); 
} 

Dal momento che non abbiamo accesso al servizio Web che si sta utilizzando, e supponendo che i dati vengono correttamente tornato, ho dovuto rimuovere il commento i dati predefiniti per fare una demo di lavoro:

Updated jsbin

+0

ok ho testato la tua soluzione ma quando ho creato nuove connessioni sta creando altri rettangoli duplicati. Se vuoi posso darti il ​​mio URL di servizio web in modo che tu possa vedere il problema reale –

+1

@Learning sarebbe di aiuto, o un paio di set con alcuni nuovi dati simulati se ti senti a disagio a condividerlo qui. – K3N

+1

In realtà quando ho già 1 record di connessione nel mio database e quando lo eseguo, funziona bene ma quando creo nuove connessioni nel database e la mia richiesta ajax recupera queste nuove connessioni quando si verifica il problema. –

1

Ho lavorato con il codice sorgente di riferimento Fiddle, che ha funzionato abbastanza bene con me.

aggiunto un paio di cose:

Prima di una funzione separata per aggiungere un utente alla matrice users. In questo modo, gli utenti possono essere facilmente aggiunti dopo una chiamata al servizio web di successo.

In secondo luogo, addded un paio di funzioni di supporto per ottenere posizioni e indicazioni casuali.

function addUser(user) { 
    users.push({ 
    id: user.UserId, 
    connections: user.Connections, 
    width: 80, 
    height: 80, 
    x: getRandomX(), 
    y: getRandomY(), 
    dir: { 
     x: getDir(), 
     y: getDir() 
    } 
    }); 
} 

// the success callback from your webservice 
// guess this receives a `user` object with Id and Connections 
// for the test we use `getRandomConnections` 
function getDataFromWebService() { 
    let newUser = { "UserId": Date.now(), "Connections": getRandomConnections() }; 
    addUser(newUser); 
} 

Fiddle

Quando si collega il webservice, è possibile abbandonare la funzione getRandomConnections e di riferimento. Nel vostro webservice successo richiamata, assicuratevi di avere un oggetto nel formato:

{ UserId: 1337, Connections: [1, 2] } 

passare l'oggetto alla funzione addUser.

+0

se si dispone di URL del servizio Web, quindi cosa si deve rimuovere dal proprio codice e cosa usare ?? –

+1

Aggiornato la mia risposta – Pimmol

+0

posso chiederti qualche suggerimento ?? –