2013-04-06 21 views
9

Ho un <div contenteditable="true" /> che l'utente può scrivere in modo abbastanza illimitato.
I dati nel div sono salvati sul cambiamento con un timestamp in un database MySQL.Salvare le modifiche in contenteditable con timestamp

Ora il mio obiettivo è di avere una piccola nota a sinistra che indica all'utente quando ogni parte del documento è stata creata (la risoluzione dovrebbe essere in giorni).

Ora, la domanda è: Come posso salvare le informazioni (quale parte è cambiata quando) migliore?

ho considerato le seguenti opzioni finora che entrambi sembrano migliorabile:

  1. Ogni volta che l'utente visita il sito alla fine del documento inserisco una bandiera (ad esempio un arco emtpy con una classe e una attributo dati che memorizza l'inizio della modifica). Questo flag viene quindi salvato nel database quando viene richiamato lo script di salvataggio. Questa opzione renderebbe molto facile mostrare la data sul lato - li metterei appena sulla stessa altezza della campata vuota e la span mi dice la data. I lati negativi sono: l'utente potrebbe cancellare accidentalmente l'intervallo di data e ora e se l'utente non chiude la finestra per un lungo periodo non vengono inseriti nuovi intervalli temporali (questo potrebbe probabilmente essere evitato inserendo un nuovo timestamp che si estende ogni X minuti, quindi l'eliminazione della parte è più rilevante)
  2. Provare a eseguire una comparazione delle stringhe ogni volta che i dati vengono passati allo script di salvataggio e salvare solo il diff con un timestamp. Poi, quando la pagina è caricata, metti tutte le parti insieme nel giusto ordine e in Javascript metti le note della data nel posto giusto. Questo suona come un sacco di spese generali per me anche se quando le parti più vecchie vengono cambiate, due parti potrebbero diventarne una, ecc. Tutto sommato, queste opzioni sembrano molto complicate.

Qualsiasi input/idee/suggerimenti altamente apprezzati!

+0

Il tipo di contenuto è strutturato o non strutturato? Se non è strutturato (come una base di codice in tempo), suggerirei di utilizzare la soluzione fornita da armel. Se è strutturato o può essere strutturato, allora la soluzione (s) fornita da MrFishie e me. –

+0

Il tipo di contenuto è strutturato o non strutturato? Se non è strutturato (come una base di codice in tempo), suggerirei di utilizzare la soluzione di fusione fornita da armel. Se è strutturato o può essere strutturato, allora la soluzione (s) fornita da MrFishie e me. Un documento non strutturato è più complesso da gestire, perché è abbastanza spesso difficile stabilire la corretta gerarchia dei cambiamenti. (Questo è sempre stato un problema molto problematico con la replica su diversi server in Lotus Notes.) Questa è la versione del commento che vorrei prendere in considerazione. –

+0

@LoekBergman: l'input è generato dall'utente e non segue alcuna struttura specifica. – Horen

risposta

12

Quello che stai cercando di implementare è la funzione chiamata "annotate" o "blame" nel mondo di controllo del codice sorgente (sebbene tu voglia solo la data di aggiornamento piuttosto che data + autore o semplicemente autore).

Per farlo correttamente, è necessario un modo per rendere diffs (php-diff potrebbe fare il lavoro) e ottenere le versioni del testo. Ci sono diverse strategie:

  • negozio la versione più recente e mantenere solo delta (come diff unificate, la mia preferenza)

  • memorizzare tutte le versioni e calcolare i delta al volo

Una volta che hai la tua versione attuale e l'elenco dei delta (puoi decisamente abbreviare la lista se più di dire alcune decine di delta e lasciare che l'utente chieda di più se davvero importante). Tu componi i delta insieme, questo è dove avviene la fase di annotazione poichè puoi fare questa parte ricordando da quale versione proviene ogni riga. La composizione è piuttosto semplice (dalle ultime, tutte le linee aggiunte nella patch che ci portano sono le ultime, l'altra deve essere spiegata, quindi ricomincia dalla prossima patch fino a raggiungere la patch più antica che vuoi trattare , le righe rimanenti provengono da quella versione o meno recenti, quindi è possibile utilizzare una bandiera che indica "prima o dopo").

Google has a diff library for Javascript così potrebbe fare tutto il duro lavoro sulla macchina dell'utente. Hanno anche la parte patch in questa libreria. Non ho trovato una libreria di annotazione/biasimo.

+0

Grazie - sembra una buona idea. Solo per capire meglio: Salvataggio: 1) Salvo la versione più recente, 2) Allo stesso tempo, salvo il diff che è venuto con la versione corrente. Quindi caricando (l'hai chiamato componendo): 1) Inizia con la versione corrente, 2) Prendi il nuovo diff e applicalo alla versione corrente con ad es. google javascript patch, 3) Ripetere il passaggio 2 con il prossimo diff precedente fino al completamento. Ho capito bene? – Horen

+0

sì qualcosa del genere, durante "Salvataggio" assicurati di lavorare in modo transazionale (salva la patch corrente + salva). Durante il "Caricamento", dovrai applicare le patch per fare il lavoro di annotazione.Nota che, poiché le patch sono orientate alle linee, l'applicazione annotate/patch può essere ridotta a manipolare un array di "autore e/o date", lavorando solo sulle coordinate della linea e lasciando il testo nelle sole patch (anche se possono essere redditizi per un funzione di ripristino o diff-to-version). La libreria di Google non farà la parte di annotazione per te, ma puoi trarre ispirazione dal codice. – armel

+0

Non sta chiedendo il processo di annotazione o colpa (o lode), perché questo è il processo per scoprire chi ha commesso il codice. Questo non ha nulla a che fare con la ricerca della versione corrente. Il processo che descrivi è la fusione e una buona alternativa a ciò che MrFishie e io abbiamo proposto. Vedi il commento sulla domanda generale. –

4

Un modo per ottenerlo è disporre di una tabella per le revisioni dello div. Ogni tanto, puoi aggiungere una nuova voce in questa tabella, contenente il contenuto e il timestamp, e quindi tenere traccia di tutte le revisioni di modifica. Quindi, per scoprire cosa è cambiato, puoi semplicemente confrontare due delle voci per scoprire cosa è stato aggiunto, è rimasto lo stesso e rimosso.

+0

È una buona idea. L'unico problema che vedo è "come" trovare ciò che è stato aggiunto, modificato e rimosso e come abbinarlo con la posizione della data di creazione che è mostrata a sinistra. Qualche idea? – Horen

+0

Ci dovrebbe essere un modo per farlo con regex, anche se non sono molto bravo con esso. – cpdt

4

È necessario salvare queste informazioni quando l'utente invia le informazioni. Nel momento in cui l'utente vuole vedere le informazioni, ci dovrebbe essere pochissimo calcolo.

Nel backend si creano due tabelle. In una tabella, chiamiamolo 'currentdocs', si memorizza sempre l'ultima versione dei dati. Quando l'utente carica il documento, tutte le informazioni provengono da questa tabella 'currentdocs'. Nell'altra tabella, chiamiamolo 'docsintime', si salva ogni nuovo salvataggio. Ha una chiave esterna per la tabella 'currentdocs' e puoi trovare l'ultima riga in questa tabella 'docsintime' selezionando l'id massimo con quella chiave esterna. Una dichiarazione prescelta può essere qualcosa di simile:

select id from docsintime where cur_key = x order desc limit 1; 

In entrambe le tabelle si fa a memorizzare il per ogni parte rilevante l'ultimo timestamp che è stato modificato.

Quando si salva un nuovo documento, si ottiene l'ultima versione salvata nella tabella 'docsintime'. Confronta tutte le parti rilevanti con i dati di quel record. Se non differisce, copia il timestamp di quella parte rilevante nel nuovo record da salvare. Se differisce, crei un nuovo timestamp per quella parte rilevante. Dopo il confronto, si salva il nuovo record in entrambe le tabelle 'currentdocs' e 'docsintime'. Aggiorna la tabella "currentdocs" e inserisci un nuovo record nella tabella "docsintime". Solo con un nuovo documento effettuerai un inserimento nella tabella "currentdocs". Con la prossima richiesta di quel documento, dovrai solo raccogliere le informazioni dalla tabella "currentdocs". E il processo ricomincia da capo.

Problemi correlati