In diesem Artikel wird die Implementierungsidee der gemeinsamen Bilder auf der Webseite vorgestellt, um kleine Bilder vor dem Hochladen direkt auf der Seite zu generieren. In Anbetracht der Tatsache, dass diese Funktion eine bestimmte Anwendbarkeit hat, wird die relevante Logik in eine ImageUploadView -Komponente eingekapselt. Der tatsächliche Einsatzeffekt kann verwendet werden, um die Git -Renderings im nächsten Absatz anzuzeigen. Bei der Implementierung dieser Komponente verwenden wir den in den vorherigen Blogs eingeführten relevanten Inhalten wie die Erbschaftsbibliotheksklasse.js und die Event -Management -Bibliothek EventBase.js jeder Komponente, die auch einige Gedanken zur Trennung von Verantwortlichkeiten, Trennung von Leistung und Verhalten enthält. Willkommen bei Lesen und Kommunizieren.
Demonstrationseffekt:
Hinweis: Da die Codes für die Demonstration alle statisch sind, wird die von der Datei hochgeladene Komponente durch SetTimeOut simuliert. Die aufrufende Methode ist jedoch genau die gleiche wie bei der Verwendung der Upload -Komponente in meiner tatsächlichen Arbeit, sodass die Codeimplementierung des Demonstrationseffekts vollständig mit den realen funktionalen Anforderungen übereinstimmt.
Laut meinen vorherigen Blog -Ideen stellen wir zunächst die Anforderungen für diese Upload -Vorschau -Funktion vor.
1. Anforderungenanalyse
Nach den vorherigen Demonstrationsrendern sind die Analyseanforderungen wie folgt:
1) Im anfänglichen Upload -Bereich wird nur eine anklickbare Upload -Schaltfläche angezeigt. Wenn Sie auf diese Schaltfläche klicken, wird das hochgeladene Bild im nachfolgenden Vorschaltbereich angezeigt.
2) Nachdem das hochgeladene Bild zum Vorschauderbereich hinzugefügt wurde, können Sie es entfernen, indem Sie die Schaltfläche löschen.
3) Wenn die Gesamtzahl der hochgeladenen Bilder eine bestimmte Grenze erreicht, z.
4) Wenn die Gesamtzahl der hochgeladenen Bilder ein bestimmtes Limit erreicht, muss die Upload -Taste angezeigt werden, wenn ein bestimmtes Bild durch den Löschvorgang entfernt wird.
Die oben genannten Anforderungen sind sichtbar. Basierend auf Erfahrung sind die Anforderungen, die analysiert werden können, wie folgt:
1) Wenn sich die Seite im Bearbeitungszustand befindet, dh der aus der Datenbank abfragte Zustand, solange die Bildliste nicht leer ist, muss das Bild am Anfang angezeigt werden. und es muss auch steuern, ob die Upload -Schaltfläche gemäß der Länge der gefundenen Bildliste und der Upload -Grenze angezeigt wird.
2) Wenn es sich bei der aktuellen Seite um einen Zustand handelt, der nur angezeigt, aber nicht geändert werden kann, muss die Schaltfläche Upload und die Schaltfläche Löschen in der Anfangsphase entfernt werden.
Lassen Sie mich nach Abschluss der Anforderungen an die Anforderungen meine Implementierungsideen erklären.
2. Implementierungsideen
Da es sich um eine Formularseite handelt, müssen Sie ein Textfeld benötigen, wenn Sie sie nach dem Hochladen des Bildes in den Hintergrund senden möchten. Als ich also eine statische Seite machte, habe ich dieses Textfeld berücksichtigt. Nachdem ich ein neues Bild hochgeladen und das Bild gelöscht hatte, musste ich den Wert dieses Textfelds ändern. Die Struktur dieses Teils, wenn statische Seiten erstellt wurden, lautet wie folgt:
<div> <Label> Elektronische Version der ID-Karte der Rechtsperson </label> <div> <input id = "legalPersonIdpic-Input" name = "legalPersonidpic" Typ = "Hidden"> <ul id = "legalPersonidpic-view"> <li> <a href = "javaScript:; href = "#"> <i> </i> Beispiel anzeigen </a> </p> </div> </div>
Aus dieser Struktur können wir auch erkennen, dass ich den gesamten Upload -Bereich in eine UL einfügt und dann die erste UL Li als Upload -Taste benutze. Um diese Funktion zu erfüllen, sind unsere Hauptaufgaben: Hochladen und Hochladen von Rückrufen, Hinzufügen oder Löschen von Bildvoransichten und Verwalten von Textfeldwerten. Aus dieser Sicht, kombiniert mit der Idee der Trennung der Verantwortlichkeiten, erfordert diese Funktion mindestens drei Komponenten, eine für das Hochladen von Dateien verantwortlich, eine für das Bildvorschau -Management verantwortlich und die andere für die Verwaltung von Textdomänenwerten verantwortlich. Kapseln Sie diese drei Funktionen niemals paarweise oder alle zusammen. In diesem Fall ist die funktionelle Kopplung zu stark und die geschriebenen Komponenten sind erweiterbar und wiederverwendbar. Wenn zwischen diesen drei Komponenten eine Interaktion erforderlich ist, müssen wir sie nur mit Hilfe von Rückruffunktionen oder Veröffentlichungsmodus in extern genannten Schnittstellen definieren.
Die Verwaltung der Textdomänenwerte ist jedoch sehr einfach, und es spielt keine Rolle, ob sie als Komponente geschrieben ist oder nicht, aber zumindest eine Kapselung auf Funktionsebene ist erforderlich. Obwohl die Datei-Upload-Komponente nicht im Mittelpunkt dieses Artikels steht, gibt es im Internet viele fertige Open-Source-Plug-Ins, wie z. Die Funktion der Bildvorschau ist der Kerninhalt dieses Artikels. Die ImageUploadView -Komponente ist die Einkapselung. Aus Sicht der Anforderungen gibt es nur drei semantische Beispielmethoden für diese Komponente, nämlich Rendern, Anhängen und Delitem. Der Render wird verwendet, um nach Abschluss der Initialisierung die Erstvorschau -Liste anzuzeigen. Anhang wird verwendet, um nach dem Hochladen eine neue Bildvorschau hinzuzufügen, und Delitem wird verwendet, um vorhandene Bildvorschau zu löschen. Nach dieser Grundidee müssen wir nur Optionen und Ereignisse für IT entwerfen, basierend auf den Anforderungen und Erfahrung in der Komponentenentwicklung.
Aus den vorherigen Anforderungen stellten wir fest, dass das Rendern dieser ImageUploadView -Komponente vom Seitenstatus beeinflusst wird. Wenn sich die Seite im Ansichtsmodus befindet, kann diese Komponente nicht hochladen und löschen, sodass Sie in Betracht ziehen können, eine Readonly -Option hinzuzufügen. Gleichzeitig wirken sich die Upload- und Löschvorgänge auch die UI -Logik der Upload -Taste aus, die sich auf das Upload -Limit bezieht. Für die Flexibilität muss auch das Upload -Limit als Option angesehen werden. Aus den drei im vorherigen Absatz genannten Instanzmethoden definiert eine Instanzmethode gemäß Ihren früheren Erfahrungen bei der Definition von Ereignissen im Allgemeinen ein Paar von Ereignissen, genau wie das Plug-In von Bootstrap. Beispielsweise kann die Render -Methode einen Render definieren. Dieses Ereignis wird ausgelöst, bevor die Hauptlogik des Renders ausgeführt wird. Wenn der externe Hörer die Verhinderung der Verhinderung () () dieses Ereignisses aufruft, wird die Hauptlogik des Renders nicht ausgeführt. Es gibt auch ein Ereignis, das nach der Ausführung der Hauptlogik des Renders ausgelöst wird. Der Vorteil dieses paarweisen Definitionsereignisses besteht darin, dass es nicht nur externe Methoden zur Erweiterung der Komponentenfunktionalität bietet, sondern auch die Verwaltung des Standardverhaltens des Komponenten erhöht.
Schließlich habe ich aus meiner früheren Berufserfahrung zusätzlich zum Hochladen von Bildern zur Vorschau auch das Hochladen von Videos, das Hochladen von Audio, das Hochladen normaler Dokumente usw. Ein weiterer Vorteil dieser Basisklasse besteht darin, dass sie die allgemeine Logik von der HTML -Struktur vollständig trennen kann. In dieser Basisklasse werden nur gemeinsame Dinge durchgeführt, z. B. die Definition von Optionen und Komponentenverhalten (Rendern, Anhängen, Delitem) sowie das Zuhören und Auslösen allgemeiner Ereignisse. Es muss nur eine feste Schnittstelle für die Unterklasse implementieren. In der anschließenden Implementierung habe ich eine DateiElploadbaseView -Komponente definiert, um die Funktionen dieser Basisklasse zu vervollständigen. Diese Basisklasse enthält keine Logik für die HTML- oder CSS -Verarbeitung. Es wird nur die Funktionen abstrahiert, die wir ausfüllen möchten, und die Geschäftslogik nicht übernimmt. Die gemäß Geschäftslogik implementierten Unterklassen werden durch die HTML -Struktur begrenzt, sodass der Anwendungsbereich der Unterklassen gering ist. Und weil die Basisklasse vollständig von der HTML -Struktur getrennt ist, hat sie einen größeren Anwendungsbereich.
3.. Implementierungsdetails
Aus der Implementierungsidee von Teil 2 sind die zu implementierenden Klassen: FileUploadBaseView und ImageUploadView, die erstere ist die Basisklasse des letzteren. Gleichzeitig müssen wir im vorherigen Blog EventBase.js verwenden, wenn man bedenkt, dass die Komponente Ereignisverwaltungsfunktionen bereitstellen muss, und FileUploadBaseView muss die EventBase -Komponente der Bibliothek erben. In Anbetracht der Tatsache, dass es eine Klassendefinition und Vererbung gibt, müssen wir auch die zuvor geschriebene Erbbibliotheksklasse verwenden, um die Komponente und die Vererbungsbeziehung der Komponente zu definieren. Die Vererbungsbeziehung verwandter Komponenten lautet: ImageUploadView Extend FileUploadBaseView ExpeventBase.
(Hinweis: Der folgende zugehörige Code verwendet SeaJs in Modularität.)
Was FileUploadBaseView tut, sind:
1) Definieren Sie gemeinsame Optionen und gemeinsames Ereignismanagement
In der Standardkonfiguration dieser Komponente sehen Sie die Definitionen aller gemeinsamen Optionen und gemeinsamen Ereignisse:
var defaults = {data: [], // Die Liste der zu angezeigten Daten muss vom Objekttyp sein, wie z. Addition und Deletion onBforerender: $ .noop, //foreReport.bevor Ereignis, Trigger Onrender: $ .noop, //forereport.after Ereignis, bevor die Render -Methode aufgerufen wird, und OnbeForeAppend: $ .noop, // dem Append. $ .noop, // hat das Ereignis von Delitem.bevor eingehalten, löst ONDELITEM: $ .noop vor der Delitem -Methode, die mit dem Ereignis delitem.after, ausgelöst}, bezeichnet wird;In der Init -Methode der Komponente sehen Sie die Initialisierungslogik für die allgemeine Option und die Ereignisverwaltung:
Init: Funktion (Element, Optionen) {// Rufen Sie die Init -Methode der übergeordneten Klasse Eventbase über diese. this.data = Resoledata (opts.data); löschen optts.data; this.sizelimit = optts.sizelimit; this.readonly = opts.readonly; // Binding Ereignis this.on ('render.before', $ .Proxy (opts.onBeForerender, this)); this.on ('render.after', $ .proxy (optts.onrender, this)); this.on ('append.before', $ .Proxy (opts.onbeforeAppend, this)); this.on ('append.after', $ .proxy (opts.onappend, this)); this.on ('Delitem.before', $ .Proxy (optts.onbeForedElitem, this)); this.on ('Delitem.after', $ .proxy (opts.ondelitem, this));},2) Definieren Sie das Verhalten von Komponenten und Reservenschnittstellen, die durch Unterklassen implementiert werden können:
Render: function () {/*** Render ist eine Vorlage. Die Unterklasse muss die Render -Methode nicht außer Kraft setzen, sondern nur die _render -Methode* überschreiben, wenn die Render -Methode der Subklasse aufgerufen wird, die Render -Methode der übergeordneten Klasse* heißt** Wenn die Ausführung der _render -Methode die _render -Methode der Unterklasse ausgeführt wird, wird die Auslöser von Vor- und Nachher -Ereignissen zu vereinen. this.trigger (e = $ .event ('render.before')); if (e.isdefaultPrevented ()) return; this._render (); this.trigger ($. event ('render.after');}, // Unterklassen müssen die _render -method_render implementieren: function () {}, anhängen: function (item) {var e; if (! item) return; item = cresentatemaitem (item); this.stfaug (E = $ .Eld. return; thata.push (item); this._append (item); this.trigger ($. Ereignis ('append.after'), item);}, // Unterklassen müssen die _append method_append: function (data) {}, delitem: function (uUid) {var e, item = this.TeTDatem (uUid); = $ .Event ('delitem.before'), item); if (e.isdefaultPrevented () return; method_delitem: function (data) {}Um die Ereignisverteilungslogik vor und nach dem Verhalten einheitlich zu verarbeiten, wird die Hauptlogik von Render, Anhängen, Delitem in Methoden extrahiert. Wenn die Render -Methode einer Unterklasse aufgerufen wird, wird die Methode der übergeordneten Klasse tatsächlich aufgerufen, aber wenn die übergeordnete Klasse die _render -Methode ausführt, wird die Methode der Unterklasse ausgeführt und die beiden anderen Methoden sind ebenfalls ähnlich. Es ist zu beachten, dass Unterklassen die drei Methoden Rendern, Anhängen und Delitem nicht überschreiben können. Andernfalls müssen Sie die Triggerlogik verwandter Ereignisse selbst verarbeiten.
Die Gesamtimplementierung von FileUploadBaseView ist wie folgt:
Define (function (fordert, exports, modul) {var $ = require ('jQuery'); var class = required ('mod/class'); var eventBase = Request ('mod/eventBase'); 'yyyy.png'}] SizElimit: 0, // Um die Anzahl der in BaseView angezeigten Elemente zu begrenzen, bedeutet dies, wenn 0 keine Grenze readonly: false, //, um in BaseView Elemente zu kontrollieren, dürfen hinzugefügt und gelöscht auf Bebforerender: $ .noop, entsprechendem Render. onbeForeAppend: $ .noop, // entsprechende append.bevor Ereignis, Trigger onAppend: $ .noop, // entsprechende Anhänge. Nach Ereignis, Auslöser aufbeforedElitem: $ .noop, // entsprechend append.after Ereignis, Auslöser auf dem Delitem.bevor Ereignis, Trigger ONDELITEM: $ .noop // entsprechend Delitem.Af Ereignis, Trigger};/*** Datenverarbeitung, fügen Sie jedem Datensatz von Daten ein _UUID -Attribut hinzu. Zeit);});} Funktion gelöstataitem (Daten, Zeit) {Zeit = Zeit || Ereignisbase durch diese. $ .Proxy (optts.onbeForerender, this); this.on ('Delitem.before', $ .Proxy (optts.onbeForedElitem, this)); Standardeinstellungen;}, getDataitem: function (uUid) {// DateItemReturn that.data.filter (Funktion (item) {return item._uuid === uUid;}) [0];}, getDataTemindex: Funktion (uUid) {var ret; {this.data. && (ret = i);}); Operationen vor und nach Ereignissen*/var e; {var e; if (! item) return; item = regeltedataitem (item); this.trigger (e = $ .event ('append.vor'), item); if (e.isdefaultPrevented () return; _Append method_append: function (data) {}, delitem: function (uUid) {var e, item = this.getDataitem (uUid); if (! item) return; return;this.data.splice(this.getDataItemIndex(uuid), 1);this._delItem(item);this.trigger($.Event('delItem.after'), item);},//Subclasses need to implement the _delItem method_delItem: function (data) {}}, extend: EventBase,staticMembers: {Standards: Standards}}); return FileUploadBaseView;});Die Implementierung von ImageUploadView ist relativ einfach, ähnlich wie das Ausfüllen der Lücken. Es gibt ein paar Punkte zu erklären:
1) Die Standardeinstellungen dieser Klasse müssen die Standardeinstellungen der übergeordneten Klasse erweitern, um die Standardoptionen dieser Unterklasse hinzuzufügen und auch die Definition der Standardoptionen der übergeordneten Klasse beizubehalten. Gemäß der statischen Seitenstruktur wurde ein OnAppendClick -Ereignis hinzugefügt, und die relevanten Methoden der Datei -Upload -Komponenten können in diesem Event extern aufgerufen werden:
// Erben Sie und erweitern Sie die Standard -Standardsvar der übergeordneten Klasse defaults = $ .extend ({}, FileUploadBaseView.Defaults, {onAppendClick: $ .noop // Callback beim Klicken auf die Upload -Schaltfläche Upload});2) In der Init -Methode muss die Init -Methode der übergeordneten Klasse aufgerufen werden, um diese allgemeine logische Verarbeitung abzuschließen. Am Ende von Init müssen Sie die Render -Methode manuell aufrufen, damit Sie den Effekt nach dem Instanziieren der Komponente sehen können:
Andere Implementierungen sind rein geschäftslogische Implementierungen und sind eng mit den Anforderungen von Teil 2 verbunden.
Die Gesamtimplementierung von ImageUploadView ist wie folgt:
Define (function (fordert, exports, modul) {var $ = require ('jQuery'); var class = required ('mod/class'); var FileUploadBaseView = Require ('mod/FileUploadBaseView'); // Inherit und erweitert die DefaultSvar -Defaults = $. $ .noop // Rückruf beim Klicken auf die Schaltfläche Upload}); var ImageUploadView = class ({InstanCemembers: {init: function (Element, Optionen) {var $ element = this. $ element = $ (Element); var opts = this.getOptions (Optionen); // rufen Sie die Init -Methode an. Optionen); // Fügen Sie die Upload- und Löschen von Hörern hinzu und Triggerverarbeitung if (! this.readonly) {var that = this; that.on ('appendClick', $ .Proxy (opts.onappendClick, this); that.trigger ('appendClick');}); {return defaults;}, _ setItemaddhtml: function () {this. $ element.prepend ($ ('<li> <a href = "javaScript:;">+</a> </li>'); () {var html = [], dass = this; // Wenn es sich nicht um einen schreibgeschützten Zustand handelt und die Upload-Grenze nicht erreicht hat, fügen Sie die Upload-Taste hinzu, wenn (! {html.push (that._getItemrenderHtml (item))}); src = "', item.url,'"> ', this.readonly? this. $ element.find ('li.view-item-add'); // Wenn das Upload-Limit erreicht wurde, entfernen (! Data._UUID) .Remove (); this._dealwithsizelimit ();}}, erweitern: FileUploadBaseView});4. Demo -Anweisungen
Die Demo -Projektstruktur lautet:
Was gerahmt ist, ist der Kerncode der Demonstration. Darüber hinaus sind FileUploadbaSerview.js und ImageUploadView.js die beiden Kernkomponenten, die in der vorherigen Implementierung implementiert sind. DateiElploader.js wird verwendet, um Hochladungskomponenten zu simulieren. Die Instanz hat einen Onsuccess -Rückruf, der darauf hinweist, dass der Upload erfolgreich ist. Es gibt auch ein OpenChooseFilewin, mit dem der Prozess des Öffnens des Fensters der Auswahldatei und das Hochladen von es simuliert wird:
Define (function (fordert, exports, modul) {return function () {var imglist = ['../img/1.jpg'','../img/2.jpg'.'../img/3.jpg','.' ../img/4.jpg'], I = 0; function () {setTimeout (function () {that.OnuSuSuSuSuccess (imglist [i ++]); if (i == imglist.length) {i = 0;}}, 1000);}}});App/Regist.js ist der logische Code der Demonstrationsseite, und die Schlüsselteile wurden mit Kommentaren erklärt:
Define (function (fordert, exports, modul) {var $ = require ('jQuery'); var imageUploadView = required ('mod/imageUploadview'); var FileUpleLader = Request ('mod/fileUpload'); // Dies ist eine Datei -Upload -Komponente, die durch Asynchronen -Dateien simuliert ist. erfolgreich hochgeladen und nach der ImageUploadView-Komponente einen bestimmten Artikel löscht den Wert von $ legalPersonidpic var $ legropersonIdpic = $ ('#legalPersonidpic-Input'), data = json.Parse ($ legalPersonidpic.val () || '[]') // Data, die mit dem Antrag auf Beispiel geladen werden. ImageUploadView -Komponente // speichern Sie nach dem Hochladen des Datei -Uploads die neu geladene Datei auf den Wert von $ legalPersonIdpic // $ legalPersonIdpic Stores var appendimageInputValue = Funktion ($ Eingabe, Element) {var value = json.parse ($ input.val () || '[]'); value.push (item); '[]'), index; value.foreach (Funktion (item, i) {if (item._uuid === uUid) {index = i;}}); value.spled (index, 1); = {url: uploadValue}; legalPersonIdpicView.Append (item); appendimageInputValue ($ legalPersonIdpic, item); FileUlloader.openchooseFileWin ();}, OnDelItem: Funktion (Daten) {removeImageInputValue ($ legalPersonIdpic, data._uuid);}});});5. Zusammenfassung dieses Artikels
Die ImageUploadView -Komponente ist am Ende nicht schwer zu implementieren, aber ich habe auch viel Zeit damit verbracht, darüber nachzudenken, und andere übergeordnete Klassen, um sie zu implementieren, und die meiste Zeit wurde die Trennung von Verantwortlichkeiten und Verhaltenstrennung verbracht. Die Ansichten zu diesen beiden Aspekten von Programmierideen, die in diesem Artikel ausgedrückt werden, sind nur meine persönliche Erfahrung. Aufgrund der abstrakten Ebene werden alle Denkmethoden und das endgültige Verständnis nicht gleich sein. Daher kann ich nicht direkt sagen, ob ich Recht oder falsch bin. Der Zweck des Schreibens ist es, zu teilen und zu kommunizieren und zu prüfen, ob es andere erfahrene Freunde gibt, die bereit sind, Ihnen in dieser Hinsicht über ihre Ideen zu informieren. Ich glaube, nachdem jeder zu viel über die Ideen anderer Menschen gelesen hat, werden sie auch seiner eigenen Programmierungsideentraining helfen.