Das Gmail Label Chooser Rätsel - gibt es einen besseren Weg es zu tun?

9

Wir sind dabei, genau wie gmail für unsere webapp eine Labelfunktionalität zu implementieren - Sie können die Posts (Checkboxen) auswählen und auswählen, welche Labels angewendet / gelöscht werden sollen aus einer Drop-Down-Liste von Labels (die selbst ein Reihe von Kontrollkästchen). Das Problem ist, "wie man es macht?" Ich habe eine Lösung und bevor ich es auf diese Weise anwende, möchte ich eine Meinung darüber bekommen, ob es der richtige Weg ist und ob es vereinfacht werden kann, bestimmte jquery / javascript Konstrukte zu benutzen, die mir vielleicht nicht bewusst sind. Ich bin noch kein JavaScript / jQuery-Pro. :)

Lass: M = {Satz von Posts} N = {Etikettensatz} M_N = Viele-zu-viele-Beziehung zwischen M und N, d. H. Die Menge von Posts, die mindestens eine Markierung von N

haben

Ausgabe: Eine Reihe von 'ausgewählten' Posts und die Menge der 'ausgewählten' Labels erhalten ein Array von Elementen für den JSON mit den folgenden Werten:

  • Post_id, Label_id, Aktion {hinzufügen, löschen}

Hier ist der Ansatz, den ich mir ausgedacht habe (naiv oder optimal, ich weiß es nicht):

  1. Aktuelle Anzahl der ausgewählten Posts abrufen: var selectionCount = 5 (z. B. 5 ausgewählte Posts)
  2. Erfassen Sie den folgenden Datensatz für jedes Element in der Auswahl:
%Vor%

Im Grunde nimmt die obige Datenstruktur nur die Bedingungen der Anzeige auf, dh 5 Beiträge werden insgesamt ausgewählt und nur zwei haben die Bezeichnung "x", dann sollte die Etikettenliste ein "teilweises Häkchen" in der Checkbox zeigen, wenn alles Posts haben ein Label "y", dann zeigt das Drop-down ein "full tick". Labels, die nicht auf dem ausgewählten Set sind, sind nur nicht ausgewählt, können aber nur zu einem Häkchen oder 'keiner' wechseln, aber nicht zu einem partiellen Zustand (dh nur on / off. Der partielleTick hat sozusagen drei Zustände: ein / aus / teilweise)

Die Spalte 'newState' ist im Grunde die Auswahl. Die Ausgabeaktion basiert auf dem vorherigen Zustand (d. H. CurrentStateToShow):

  • partially to tick impliziert das Hinzufügen eines Labels zu allen Posts , die dieses Label nicht haben
  • markiert mit "none" bedeutet, dass das Label von allen Posts gelöscht wird
  • partially to none bedeutet, dass nur Labels von diesen ausgewählten Posts gelöscht werden
  • none to ticked impliziert, dass allen Posts neues Label hinzugefügt wird
  • partially zu partially impliziert ignore, d. h. keine Änderung .

Dann kann ich über diese Menge iterieren und entscheide, die folgenden Daten an den Server zu senden:

%Vor%

und so weiter.

Was ist das Problem? Nun, das ist voll KOMPLIZIERT !!! Javascript hat nicht wirklich die Kartendatenstruktur (tut es?) Und es würde zu viele sequenzielle Iterationen beinhalten und jedes Ding überprüfen und dann viele if-else haben, um den Wert von newState festzustellen.

Ich bin nicht auf der Suche nach "wie man es programmiert", aber was kann ich tun, um mein Leben einfacher zu machen? Gibt es da draußen etwas, das ich schon benutzen kann? Ist die Logik korrekt oder ist sie etwas zu verschachtelt? Irgendwelche Vorschläge, wie man das Problem oder einige eingebaute Datenstrukturen (oder eine externe Lib) angreift, die die Dinge weniger grob machen könnten? Codebeispiele: P?

Ich arbeite mit javascript / jquery + AJAX und restlet / java / mysql und werde dafür eine JSON-Datenstruktur senden, aber ich bin von diesem Problem ziemlich fertig. Es sieht nicht so einfach aus, wie ich es ursprünglich gedacht hatte (ich meine, ich dachte, es sei "einfacher" als das, was ich jetzt vorstelle):

Ich dachte ursprünglich daran, alle Daten an den Server zu senden und dies alles im Backend durchzuführen. Aber nachdem eine Bestätigung empfangen wurde, muss ich das Frontend auf eine ähnliche Art und Weise aktualisieren, so dass ich sozusagen "zurück auf Platz eins" war, da ich dasselbe am Frontend wiederholen müsste, um zu entscheiden, welche Labels zu verstecken sind und was zu zeigen. Daher dachte ich, es wäre einfach besser, das Ganze auf der Client-Seite zu machen.

Ich vermute, dass dies eine einfache 100-150 + Zeilen Javascript / Jquery-Code nach meinem "Know-how" sozusagen, vielleicht aus ... aber das ist, warum ich hier bin: D

PS: Ich habe diesen Post und die Demo angeschaut Wie kann ich einen Gmail-ähnlichen Label-Chooser implementieren? Aber diese Demo ist nur für einen Beitrag nach dem anderen und kann leicht gemacht werden. Mein Problem wird durch die Auswahl, die mit diesen Teilauswahlen gesetzt wurde, erschwert.,

    
PhD 10.07.2011, 18:38
quelle

1 Antwort

5

Algorithmus

Ich denke, der Algorithmus macht Sinn.

Aber, gibt es eine Menge If-els, um die Output-Aktion zu berechnen? Warum nicht einfach ein abgeheftetes Label zu ALLEN Posts hinzufügen - sicherlich kann man nicht zweimal ein Label zum selben Post hinzufügen. Ich bezweifle, dass es die Leistung beeinträchtigen würde ... Vor allem, wenn Sie JSON-Daten für alle geänderten Posts sowieso in eine Anfrage einfügen (das hängt davon ab, ob Ihr Back-End das gleichzeitige Einfügen mehrerer Objekte unterstützt).

Beat Komplexität mit MVC

In Bezug darauf, wie es weniger komplex gestaltet werden könnte: Ich denke, die Code-Organisation ist hier eine große Sache.

Es gibt etwas, das Sie verwenden können: Ich empfehle Ihnen, Bibliotheken zu überprüfen, die eine Art von MVC-Ansatz in JavaScript implementieren (zum Beispiel Backbone.js ). Sie werden am Ende einige Klassen haben und Ihre Logik wird in kleine Methoden für diese Klassen passen. Ihre Datenspeicherlogik wird von "Modell" -Klassen und Anzeigelogik nach "Ansichten" behandelt. Dies ist wartungsfreundlicher und testbar.

(Bitte schauen Sie sich diese beiden tollen Präsentationen zum Thema an, falls Sie nicht bereits: Erstellen großer jQuery-Anwendungen , Funktionalitätsorientierte Code-Organisation .)

Das Problem besteht darin, dass das Refactoring des vorhandenen Codes einige Zeit in Anspruch nehmen kann, und es ist schwierig, es vom ersten Moment an richtig zu machen. Es wirkt sich auch auf Ihre gesamte clientseitige Architektur aus, so dass Sie das vielleicht nicht wollten.

Beispiel

Wenn ich eine ähnliche Aufgabe hätte, würde ich Backbone.js nehmen und so etwas machen (Pseudocode / CoffeeScript; dieses Beispiel ist weder gut noch vollständig , das Ziel ist es, eine grundlegende Idee zu geben des klassenbasierten Ansatzes im Allgemeinen):

%Vor%

Hoppla, scheint zu viel Code zu sein. Wenn das Beispiel unklar ist, können Sie gerne Fragen stellen.

( Aktualisieren Sie nur, um zu verdeutlichen: Sie können genau in JavaScript genauso machen. Sie erstellen Klassen, indem Sie extend() Methoden von Objekten aufrufen, die von Backbone bereitgestellt werden schneller, um es so zu tippen.)

Sie würden wahrscheinlich sagen, dass das noch komplexer ist als die ursprüngliche Lösung. Ich würde argumentieren: Diese Klassen liegen normalerweise in separaten Dateien [1], und wenn Sie an einem Stück arbeiten (zB die Darstellung von Label in DOM), beschäftigen Sie sich normalerweise nur mit einem von ihnen ( LabelView ). Schauen Sie sich auch die oben genannten Präsentationen an.

[1] Über die Code-Organisation, siehe "Brunch" -Projekt unten.

Wie das obige Beispiel funktioniert:

  1. Der Benutzer wählt einige Posts aus:

    • Click-Handler für die Post-Ansicht:
      1. schaltet den aktivierten Status des Posts um.
      2. aktualisiert alle LabelManager-Status aller Labels.
  2. Der Benutzer wählt eine Bezeichnung:

    • Der Klick-Handler in der Label-Ansicht schaltet den Status des Labels um.
  3. Der Benutzer klickt auf "Übernehmen":

    • apply_handler() : Führen Sie für jede der geänderten Beschriftungen die entsprechende Aktion für jeden ausgewählten Beitrag aus.

Backbone.js

Aktualisierung als Antwort auf einen Kommentar

Nun, Backbone ist eigentlich nicht viel mehr als ein paar Basisklassen und Objekte (siehe kommentierte Quelle ).

Aber ich mag es trotzdem.

  • Es bietet eine gut durchdachte Konventionen für die Code-Organisation.

    Es ist viel wie ein Framework: Sie können es im Grunde nehmen und sich auf Ihre Informationsstruktur, Repräsentation und Geschäftslogik konzentrieren, anstatt "wo soll ich dies oder das hinstellen, damit ich nicht mit Wartungs-Albtraum enden werde ". Allerdings ist es kein Rahmen, was bedeutet, dass Sie immer noch viel Freiheit haben, um zu tun, was Sie wollen (einschließlich sich selbst in den Fuß zu schießen), aber auch einige Designentscheidungen selbst treffen müssen / p>

  • Es speichert eine gute Menge von Boilerplate-Code.

    Wenn Sie beispielsweise eine RESTful-API vom Back-End bereitgestellt haben, können Sie diese einfach Backbone-Modellen zuordnen und alle Synchronisierungsarbeiten für Sie ausführen: z. Wenn Sie eine neue Model -Instanz speichern - & gt; Es wird eine POST-Anforderung an die URL Collection gesendet, wenn Sie das vorhandene Objekt aktualisieren - & gt; Es gibt eine PUT-Anforderung an die URL dieses bestimmten Objekts aus. (Request Payload ist der JSON von Modellattributen, den Sie mit der Methode set() festgelegt haben.) Sie müssen also nur URLs einrichten und die Methode save() für das Modell aufrufen, wenn Sie sie speichern möchten fetch() , wenn Sie den Status vom Server abrufen müssen. Es verwendet jQuery.ajax() hinter den Kulissen, um tatsächliche AJAX-Anfragen durchzuführen.

Einige Referenzen

  • Einführung in Backbone.js (inoffiziell aber cool) (gebrochen)

  • Das ToDos Beispiel

    Nehmen Sie es nicht als "offizielles" Backbone.js-Beispiel, obwohl es von den Dokumenten referenziert wird. Zum einen verwendet es keine Router, die später eingeführt wurden. Im Allgemeinen würde ich sagen, dass es ein gutes Beispiel für eine kleine Anwendung ist, die auf Backbone basiert, aber wenn Sie an etwas Komplexem arbeiten (was Sie tun), werden Sie wahrscheinlich mit etwas ein bisschen anders enden.

  • Während Sie dabei sind, sollten Sie Brunch ausprobieren. Es bietet im Grunde eine Projektvorlage mit CoffeeScript, Backbone.js, Underscore.js, Stitch, Eco und Stylus.

    Dank der strikten Projektstruktur und der Verwendung von require() erzwingt es höhere Code-Organisationskonventionen als Backbone.js allein. (Sie müssen im Grunde nicht nur darüber nachdenken, in welcher Klasse Sie Ihren Code platzieren, sondern auch in welcher Datei diese Klasse abgelegt werden soll und wo diese Datei in das Dateisystem eingefügt werden soll.) Wenn Sie jedoch kein "konventioneller" sind Art von Person, dann wirst du es wahrscheinlich hassen. Ich mag es.

    Was toll ist, ist, dass es auch eine Möglichkeit bietet, all diese Dinge einfach zu erstellen. Sie führen einfach brunch watch aus, fangen an, an dem Code zu arbeiten, und jedes Mal, wenn Sie Änderungen speichern, kompiliert und erstellt das gesamte Projekt (dauert weniger als eine Sekunde) in ein build -Verzeichnis und verkettet (und wahrscheinlich minimiert es) alle resultierenden Javascript in eine Datei. Es führt auch Mini Express.js Server auf localhost:8080 aus, was Änderungen sofort widerspiegelt.

Verwandte Fragen
Tony 11.07.2011, 01:43
quelle

Tags und Links