[RUBY] Wenn Sie in Ihrem Herzen denken, "Ersetzen Sie das Produktbild"! Zu diesem Zeitpunkt ist die Aktion beendet! ~ part4 ~

Annahme

--Verwenden Sie Rubin auf Schienen 6.0.0.

Einführung

Dies ist die Zusammenfassung des letzten Males (Teil 3) . Ich habe so etwas und so etwas mit jQuery auf dem neuen Registrierungsbildschirm implementiert.

Der aktuelle Status ist, dass beim Auswählen eines Bildes ein neues Formular angezeigt wird und beim Drücken von Löschen verschwindet. Auf den ersten Blick sieht es so aus, als wäre es erledigt, aber da dies alles Aktionen von js sind, verschwinden sie auf dem neu geladenen Bearbeitungsbildschirm.

In diesem Teil wird also beispielsweise ein neues Formular auf dem Bearbeitungsbildschirm angezeigt.

Die Einführung und das Verfahren sind übrigens ausführlich in <a href="https://qiita.com/silvercrow222/items/55aeb5d13ec2bde305db""> Teil1 beschrieben. Schauen Sie also bitte vorbei, wenn Sie interessiert sind.

Lass es uns versuchen

Es gibt drei Hauptaufgaben.

Etwas wie das. Ich mache es sofort, aber ich muss dem Controller ein wenig hinzufügen, bevor ich mit der Ansichtsdatei spielen kann. Beginnen wir also von dort aus.

app/controllers/products_controller.rb


#~Kürzung~
  private
  def product_params
    params.require(:product).permit(:name, images_attributes: [:src, :_destroy, :id]).merge(user_id: current_user.id)
  end
#~Kürzung~
end

Ich habe dem starken Parameter eine kleine Beschreibung hinzugefügt. Diese _Destroy ist ein Schlüssel, der die Informationen des zugeordneten untergeordneten Modells löscht. Es ist eine ungewohnte Form, aber es ist ein anständiger Schlüssel, also mach dir keine Sorgen.

Nun schreiben wir die Ansichtsdatei.

haml:app/views/products/_form.html.haml


= form_with model: @product, local: true do |f|
  = f.text_field :name, placeholder: 'name'
  #image-box
    // ~Kürzung~
    - if @product.persisted?
      .group{ data: { index: @product.images.count } }
        = file_field_tag :src, name: "product[images_attributes][#{@product.images.count}][src]", class: 'file'
        .remove
Löschen
  = f.submit 'SEND'

Ich habe den @ product.persisted? Part hinzugefügt. Es sieht schwierig aus, aber ich konvertiere nur den Formularteil, den ich das letzte Mal in jQuery hinzugefügt habe, in das Haml-Format. Ich versuche ein neues Formular anzuzeigen.

Dies bleibt bestehen. Bestimmt, ob die von Ihnen verwendete Instanz gespeichert wurde. Der Punkt ist, ob es sich um neue oder bereits registrierte Informationen handelt. Denken Sie daran, es ist sehr praktisch.

Ich konnte es anzeigen, aber die aktuelle Schaltfläche zum Löschen kann die bereits in der Datenbank registrierten Informationen nicht löschen. Sie müssen es also mit dem soeben hinzugefügten _destroy-Schlüssel löschen können.

haml:app/views/products/_form.html.haml


= form_with model: @product, local: true do |f|
  = f.text_field :name, placeholder: 'name'
  #image-box
    = f.fields_for :images do |i|
      // ~Kürzung~
      - if @product.persisted?
        = i.check_box :_destroy, data: { index: i.index }, class: 'hidden'
  - if @product.persisted?
    // ~Kürzung~
  = f.submit 'SEND'

Neben dem vorherigen habe ich auch einen Satz mit persistiertem? In der Bildbox hinzugefügt. Wenn Sie das Kontrollkästchen mit dem Schlüssel _destroy aktivieren, wird der entsprechende Datensatz aus der Datenbank gelöscht. Ich werde nicht näher darauf eingehen, warum dies passiert (weil ich es nicht vollständig verstehe ...), aber ich denke, es ist eine gute Idee, sich daran zu erinnern, wie man es so schreibt.

Jetzt ist der Mechanismus selbst abgeschlossen. Es ist jedoch nicht gut, dass es ein Kontrollkästchen gibt, das von der Schaltfläche "Löschen" getrennt ist. Daher werden wir diese verknüpfen.

app/assets/javascripts/product.js


$(function() {
  // ~Kürzung~
  $('.hidden').hide();
  $('#image-box').on('click', '.remove', function() {
    //Ruft den eindeutigen Index ab, der dem Formular zugewiesen ist.
    const targetIndex = $(this).parent().data('index')
    //Aktivieren Sie das Kontrollkästchen für den erhaltenen Index.
    const hiddenCheck = $(`input[data-index="${targetIndex}"].hidden`);
    //Wenn es ein Kontrollkästchen gibt, aktivieren Sie es.
    if (hiddenCheck) hiddenCheck.prop('checked', true);
    ~Kürzung~
  });
});

Verarbeitung zum Klickereignis der Bildbox hinzugefügt. Ich habe auch einen zeilenweisen Kommentar geschrieben. Das ist einfach. Wenn Sie also die Grundlagen von jQuery kennen, ist es in Ordnung.

Sie können dies auch überprüfen, indem Sie auf die Schaltfläche Löschen klicken. Lassen Sie uns das Kontrollkästchen ausblenden. Diesmal habe ich js .hide () verwendet, aber Sie können die Anzeige einstellen: keine in CSS.

Schließlich wird die Indexabdeckung verhindert und die Implementierung abgeschlossen.

app/assets/javascripts/product.js


$(function() {
  // ~Kürzung~
  let fileIndex = [1,2,3,4,5]
  lastIndex = $('.group:last').data('index');
  fileIndex.splice(0, lastIndex);
  // ~Kürzung~
});

Fügen wir dem Definitionsteil von fileIndex eine Beschreibung hinzu. Die Idee ist, den zuletzt verwendeten Index abzurufen und den Dateieindex-Wert durch diesen Wert zu ersetzen.

In Bezug auf .splice ist dies übrigens eine hervorragende Methode, mit der Sie aus den angegebenen Elementen so viele Elemente zählen können, wie Sie möchten, und dann auch Elemente hinzufügen können.

Dieses Mal werden alle Werte nach der durch das erste Argument angegebenen Zahl entfernt und der durch das zweite Argument angegebene Wert eingefügt. Da es viele Dinge gibt, die getan werden können, gibt es einige komplizierte Teile schriftlich, also schauen Sie bitte genauer hin.

Die Implementierung der Bearbeitungsfunktion selbst ist übrigens abgeschlossen!

Schließlich

Es ist endlich fertig. Es war lang.

Ich denke, es ist gut zu sagen, dass wir den "Austausch von Bildern nacheinander" in den Spezifikationen erreicht haben. Fügen Sie anschließend zum besseren Verständnis eine Vorschau des Bildes hinzu, und fertig.

Sie können die Stimme des Himmels hören, indem Sie eine Vorschau des Bildes im Artikel anzeigen, bevor Sie eine Vorschau des Bildes in der App anzeigen, aber das ist mir egal. Es tut mir leid, dass es schwer zu lesen ist.

Wir sehen uns im nächsten Teil! !!

Ich möchte eine Funktion zum Bearbeiten von Produktinformationen implementieren ~ part5 ~

Recommended Posts

Wenn Sie in Ihrem Herzen denken, "Ersetzen Sie das Produktbild"! Zu diesem Zeitpunkt ist die Aktion beendet! ~ part4 ~
Wenn Sie Ihre Container nur in der Cloud ausführen möchten, ist Azure Container Instances ganz einfach
Like-Funktion Der Teil, der feststeckt, um es asynchron zu machen
[Schienen] Über den Fehler, dass das Bild nicht in der Produktionsumgebung angezeigt wird