2013-04-06 7 views
9

Ich habe eine <div contenteditable="true" />, dass der Benutzer schreiben kann, ist ziemlich unbegrenzt in der Länge.
Die Daten im Div werden bei Änderung mit einem Zeitstempel in einer MySQL-Datenbank gespeichert.Speichern Sie Änderungen in contenteditable mit Zeitstempel

Jetzt ist mein Ziel, eine kleine Notiz auf der linken Seite zu haben, die dem Benutzer sagt, wann jeder Teil des Dokuments erstellt wurde (Auflösung sollte in Tagen sein).

Nun ist die Frage: Wie kann ich die Informationen (welcher Teil hat sich wann geändert) am besten speichern?

als ich die folgenden Optionen so weit, die beide scheinen verbesserungsfähig:

  1. Jedes Mal, wenn der Benutzer die Seite am Ende des Dokuments besucht füge ich einen Flag (zB eine emtpy Spannweite mit einer Klasse und einem Datenattribut, das den Beginn der Bearbeitung speichert). Dieses Flag wird dann in der Datenbank gespeichert, wenn das Sicherungsskript aufgerufen wird. Diese Option würde es sehr einfach machen, das Datum auf der Seite zu zeigen - ich würde sie einfach auf die gleiche Höhe wie die leere Spanne setzen und die Spanne sagt mir das Datum. Nachteile sind: Der Benutzer könnte versehentlich den Zeitstempelbereich löschen und wenn der Benutzer das Fenster für eine lange Zeit nicht schließt, werden keine neuen Zeitspannespannen eingefügt (dies könnte wahrscheinlich vermieden werden, indem neue Zeitstempelspannen alle X Minuten eingefügt werden, so dass der Löschteil ist) relevanter)
  2. Der Versuch, jedes Mal, wenn die Daten an das Sicherungsskript übergeben werden, einen Vergleich der Zeichenketten durchzuführen und nur die Diff mit einem Zeitstempel zu speichern. Dann, wenn die Seite geladen ist, fügen Sie alle Teile in der richtigen Reihenfolge zusammen und legen Sie in Javascript die Datumsangaben an die richtige Stelle. Das hört sich für mich nach viel Overhead an, aber wenn ältere Teile geändert werden, können zwei Teile zu einem werden usw. Alles in allem klingt diese Option sehr kompliziert.

Alle Eingaben/Ideen/Vorschläge sehr geschätzt!

+0

Ist die Art des Inhalts strukturiert oder unstrukturiert? Wenn es unstrukturiert ist (wie eine Codebasis in der Zeit), würde ich vorschlagen, die von armel bereitgestellte Lösung zu verwenden. Wenn es strukturiert ist oder strukturiert werden kann, dann die Lösung (en) von MrFishie und mir. –

+0

Ist die Art des Inhalts strukturiert oder unstrukturiert? Wenn es unstrukturiert ist (wie eine Codebasis in der Zeit), würde ich vorschlagen, die von armel bereitgestellte Merging-Lösung zu verwenden. Wenn es strukturiert ist oder strukturiert werden kann, dann die Lösung (en) von MrFishie und mir. Ein unstrukturiertes Dokument ist komplizierter zu handhaben, da es oft schwierig ist, die richtige Hierarchie von Änderungen festzulegen. (Dies war bei der Replikation über verschiedene Server in Lotus Notes immer ein sehr problematisches Problem.) Dies ist die Version des Kommentars, die Sie berücksichtigen sollten. –

+0

@LoekBergman: Die Eingabe ist benutzergeneriert und folgt keiner bestimmten Struktur. – Horen

Antwort

12

Was Sie versuchen zu implementieren ist die Funktion namens "Annotate" oder "Schuld" in der Quellcode-Steuerelement Welt (obwohl Sie nur das Datum der Aktualisierung lieber als Datum + Autor oder einfach Autor).

Um das richtig zu machen, brauchen Sie eine Möglichkeit, Diffs zu machen (php-diff könnte die Aufgabe erledigen) und die Versionen des Textes zu erhalten. Es gibt mehrere Strategie:

  • Laden Sie die neueste Version und halten nur Deltas (wie Unified Diffs, meine Vorliebe)

  • speichern alle Versionen und berechnen Deltas on the fly

Sobald Sie Ihre aktuelle Version und die Liste der Deltas haben (Sie können definitiv die Liste kürzen, wenn mehr als ein paar Dutzend Delta sagen und lassen Sie den Benutzer mehr fragen, wenn wirklich wichtig). Sie verfassen die Deltas zusammen, hier findet die Annotationsphase statt, da Sie diesen Teil merken können, ab welcher Version jede Zeile kommt. Das Komponieren ist ziemlich einfach (beginnend mit dem letzten, alle Zeilen, die in dem Patch hinzugefügt werden, sind von den neuesten, die anderen müssen erklärt werden, also fange wieder mit dem nächsten Patch an, bis du den ältesten Patch erreichst, den du behandeln willst , die restlichen Zeilen stammen aus dieser Version oder frühestens, so dass einige Flags mit der Aufschrift "at or before" verwendet werden können.

Google has a diff library for Javascript so konnte die ganze harte Arbeit auf Benutzermaschine tun. Sie haben auch den Patch-Teil in dieser Bibliothek. Ich habe keine Annotate/Tadel-Bibliothek gefunden.

+0

Danke - das klingt nach einer guten Idee. Nur um es besser zu verstehen: Speichern: 1) Ich speichere die aktuellste Version, 2) Gleichzeitig speichere ich das Diff, das mit der aktuellen Version kam. Dann Laden (Sie nannten es Komponieren): 1) Beginnen Sie mit der aktuellen Version, 2) Nehmen Sie das neueste Diff und wenden Sie es auf die aktuelle Version mit z. Google Javascript Patch, 3) wiederhole Schritt 2 mit dem nächsten älteren Diff bis zum Ende. Hab ich das richtig verstanden? – Horen

+0

ja etwas wie das, während "Saving" sicher sein, um transaktional zu arbeiten (speichern aktuelle + speichern patch). Während des Ladens müssen Sie die Patches anwenden, um den Auftrag zu kommentieren.Beachten Sie, dass, da Patches linienorientiert sind, die Annotate-/Patch-Anwendung auf die Manipulation eines Arrays aus "Autor und/oder Datum" reduziert werden kann, wobei nur Zeilenkoordinaten verwendet werden und der Text in Patches allein gelassen wird Funktion wiederherstellen oder Version zu Version). Die Google-Bibliothek übernimmt keine Anmerkungen für Sie, Sie können sich jedoch von ihrem Code inspirieren lassen. – armel

+0

Er fragt nicht nach dem Prozess der Annotation oder Schuld (oder Lob), denn das ist der Prozess, um herauszufinden, wer den Code begangen hat. Das hat nichts mit der Suche nach der aktuellen Version zu tun. Der Prozess, den Sie beschreiben, verschmelzt und ist eine gute Alternative für das, was Herr Fishie und ich vorgeschlagen haben. Siehe den Kommentar zur allgemeinen Frage. –

4

Eine Möglichkeit, die Sie tun können, ist eine Tabelle für Revisionen der div. Hin und wieder können Sie dieser Tabelle einen neuen Eintrag hinzufügen, der den Inhalt und den Zeitstempel enthält, und daher alle Änderungen der Bearbeitung im Auge behalten. Um herauszufinden, was geändert wurde, können Sie einfach zwei der Einträge vergleichen, um herauszufinden, was hinzugefügt, gleich geblieben und entfernt wurde.

+0

Es ist eine gute Idee. Das einzige Problem, das ich sehe, ist "wie" zu finden ist, was hinzugefügt, geändert und entfernt wurde und wie man es mit der Position des Erstellungsdatums vergleicht, das auf der linken Seite gezeigt wird. Irgendwelche Ideen? – Horen

+0

Es sollte einen Weg geben, dies mit Regex zu tun, obwohl ich nicht sehr gut damit bin. – cpdt

4

Sie sollten diese Informationen speichern, wenn der Benutzer die Informationen übermittelt. In dem Moment, in dem der Benutzer die Information sehen möchte, sollte es kaum Berechnungen geben.

Im Backend erstellen Sie zwei Tabellen. In einer Tabelle, nennen wir es 'currentdocs', speichern Sie immer die neueste Version der Daten. Wenn der Benutzer das Dokument lädt, stammen alle Informationen aus dieser Tabelle 'currentdocs'. In der anderen Tabelle, nennen wir es 'docsintime', speichern Sie jeden neuen Speichervorgang. Es hat einen Fremdschlüssel für die Tabelle "currentdocs" und Sie können die letzte Zeile in dieser Tabelle "docsintime" finden, indem Sie die maximale ID mit diesem Fremdschlüssel auswählen. Eine SELECT-Anweisung kann so etwas wie:

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

In beiden Tabellen speichern Sie die für jeden relevanten Teil der neuesten Zeitstempel, die es geändert wurde.

Wenn ein neues Dokument gespeichert wird, erhalten Sie die zuletzt gespeicherte Version in der Tabelle 'docsintime'. Sie vergleichen alle relevanten Teile mit den Daten aus diesem Datensatz. Wenn es nicht anders ist, kopieren Sie den Zeitstempel dieses relevanten Teils in den neuen Datensatz, der gespeichert werden soll. Wenn es anders ist, dann erstellen Sie einen neuen Zeitstempel für diesen relevanten Teil. Nach dem Vergleich speichern Sie den neuen Datensatz in beiden Tabellen 'currentdocs' und 'docsintime'. Sie aktualisieren die Tabelle 'currentdocs' und fügen einen neuen Datensatz in die Tabelle 'docsintime' ein. Nur mit einem neuen Dokument werden Sie in die Tabelle 'currentdocs' eingefügt. Mit der nächsten Anfrage für dieses Dokument müssen Sie nur die Informationen aus der Tabelle 'currentdocs' sammeln. Und der Prozess beginnt von vorne.

Verwandte Themen