2012-05-29 10 views
11

potrei mancare qualcosa, ma sembra che la "magia" di Meteor ruota dati intorno vincolanti alle elementi DOM e testo aggiornamento e frammenti HTML tramite manubrio: http://docs.meteor.com/#reactivityMeteor: aggiornamento automatico della tela con i dati sottoscritti?

Questo è grande, tuttavia, quando si cerca di scrivere un'applicazione di meteoriti che visualizza i dati in tempo reale in un <canvas> elemento, non riesco a capire il "modo di meteore" per aggiornare la mia tela in cui le modifiche dei dati in tempo reale, dal momento che la tela è popolata tramite il codice JS come:

var g = canvas.getContext('2d') 
g.fillRect(x, y, w, h) 

e non il testo di backup dei dati nel modello HTML.

Sto provando a disegnare sulla tela utilizzando i dati di un Meteor.Collection.

Il mio unico pensiero è stato quello di incorporare tela-disegno di codice JS nel template HTML in un tag script popolato da manubrio Vars, ma questo sembra sbagliato dal momento che gli eventi di meteore e il codice di associazione dati è già JS lato client.

C'è un modo per ascoltare le modifiche dei dati in tempo reale, che attivano il disegno sulla tela tramite JS anziché elementi/testo HTML?

Per favore fatemi sapere se posso chiarire la questione in qualche modo

Update: risposta Tom seguito mi ha fatto notare Meteor.deps, che sembrano per consentire l'esecuzione di codice arbitrario in un contesto reattivo: http://docs.meteor.com/#on_invalidate

Proverò questo e aggiorno qui se funziona.

+0

I' Non sono sicuro se questo è ciò che intendevi per "incorporato ... in un tag script". attualmente sto facendo qualcosa di simile a mettere {{drawCanvas}} nel modello che contiene la mia tela, e faccio tutto il disegno all'interno della funzione che fa parte di Template.canvas.helper chiamato "drawCanvas", questa funzione non restituisce nulla, quindi non ottiene nulla reso, ma viene eseguito in modo che aggiorni la tela. E 'quello che hai già provato? Template.name.helper è reattivo automaticamente, purché dipenda da un ReactiveDict o da qualche modello che aggiornerà di conseguenza quando viene modificato –

+0

Ciò che intendevo per quel commento era generare dinamicamente il codice JS come una stringa nel modello (che è ovviamente strano). La mia risposta di seguito sembrava essere il modo "corretto" con Meteor – 7zark7

+0

che è davvero assurdo! Ma il mio metodo sembra a posto? L'idea è semplicemente usando un {{drawCanvas}} invisibile che non fa nulla, che viene rieseguito ogni volta che alcuni dati reattivi cambiano (quindi ridisegnando la tela) –

risposta

5

Questo funziona:

var Shapes = new Meteor.Collection('shapes') 

if (Meteor.is_client) { 
    // Function that redraws the entire canvas from shapes in Meteor.Collection 
    function drawShapes() { 
    var shapes = Shapes.find({}) 
    shapes.forEach(function(shape) { 
     // draw each on canvas 
    }) 
    } 

    var startUpdateListener = function() { 
    // Function called each time 'Shapes' is updated. 
    var redrawCanvas = function() { 
     var context = new Meteor.deps.Context() 
     context.on_invalidate(redrawCanvas) // Ensures this is recalled for each update 
     context.run(function() { 
     drawShapes() 
     }) 
    } 
    redrawCanvas() 
    } 

    Meteor.startup(function() { 
    startUpdateListener() 
    }) 
} 
+1

Questo funziona - grazie! Anche se quello che cerco personalmente è di eseguire il ridisegno completo solo all'avvio - e quindi eseguire solo ridisegni incrementali su aggiornamenti/aggiunte/cancellazioni. Hai il modo giusto di fare questo genere di cose solo all'avvio/rendering e non dopo ogni aggiornamento? Se metti query all'interno di template.rendered, non sembra funzionare. – semateos

+1

Il motivo per cui ho eseguito il ridisegno completo è che una tela non supporta la rimozione/l'aggiornamento delle singole forme. AFAIK, devi ridisegnare l'intero canvas se le forme si sovrappongono, ecc. – 7zark7

+0

@semateos È possibile ottenere tale comportamento utilizzando una libreria come Pixi.js, che imita l'Elenco di visualizzazione Flash. –

7

Forse la risposta alla tua domanda è utilizzare Collection.observe (http://docs.meteor.com/#observe) e attivare il codice di ridisegno pertinente nei vari callback.

Per esempio, qualcosa come:

Rectangles.observe({ 
    added: function(rect) { 
    var g = canvas.getContext('2d'); 
    g.fillRect(rect.x, rect.y, rect.w, rect.h); 
    }, 
    // etc 
}) 
+0

Grazie amico, non l'ho visto.Un problema nel mio caso particolare è che ho bisogno di ridisegnare l'intero canvas (ad esempio rimuovere un rettangolo richiede il ridisegno di rettangoli sotto/sopra di esso), il che implica che ho bisogno dell'intero risultato della query, non solo aggiunto/rimosso/modificato. – 7zark7

+0

Sicuro. Immagino che quello che hai sia il modo giusto per farlo allora. Vorrei che Meteor avesse un modo più semplice per impostare un contesto + affrontare l'invalidazione a proposito. –

Problemi correlati