[RUBY] Asynchrone Kommunikation im interaktiven Kommentarfeld

Einführung

Ich besuche derzeit eine Programmierschule namens TECH CAMP. Ich entwickle eine Flima-Klon-App, habe aber beschlossen, einen Kommentarbereich zu implementieren. Der Kommentarbereich der Furima-App hat ein dialogähnliches Erscheinungsbild zwischen dem "Aussteller" und "anderen", daher werde ich hauptsächlich über die Punkte schreiben, die ich bei dieser asynchronen Kommunikation entwickelt habe.

Was Sie erreichen wollen

Ich möchte das Kommentarfeld durch asynchrone Kommunikation aktualisieren, damit das Erscheinungsbild der Ansicht zwischen dem Verkäufer und anderen Personen (Kunden) verzweigt wird. Das fertige Beispiel ist wie folgt.

★ Wenn der Kunde Beiträge veröffentlicht

3c528fb36058573b4181cbd20e09df22.gif

★ Wenn vom Verkäufer gepostet

81970b7d86e801a61e0b752d6c4322df.gif

Verfahren

Dieses Mal werde ich mich unter der Annahme, dass das normale Posten von Kommentaren abgeschlossen ist, auf die nachfolgende Desynchronisation konzentrieren und die Prozedur schreiben.

--Bearbeiten Sie die Aktion zum Erstellen des Controllers --Erstellen Sie eine neue Jbuilder-Datei --Erstellen einer JS-Datei

Bearbeiten Sie die Erstellungsaktion des Controllers

Es gibt zwei Punkte.

Der erste Punkt ist, dass die Instanzvariablen "@item" und "@comment" während der Erstellungsaktion erstellt werden. @item extrahiert den Datensatz des kommentierten Produkts und @comment speichert den gespeicherten Kommentardatensatz. Diese Instanzvariablen werden dann von jbuilder für die jsonisierung verwendet.

Der zweite Punkt ist, dass "format.html" in reply_to hinzugefügt wird, sodass jQuery auch im HTML-Format antworten kann, wenn es nicht geladen ist. Wie später beschrieben wird, gibt es Fälle, in denen die js-Datei nicht richtig geladen wird, wenn Turbolinks zusammen verwendet werden. Natürlich wäre es am besten, wenn es richtig verwaltet werden könnte, aber ich denke, dass es viele Leute gibt, die das Team zum ersten Mal entwickeln, also dachte ich, dass eine solche Versicherung notwendig wäre, also schrieb ich es.

comments_controller.rb


class CommentsController < ApplicationController
  def create
    @item = Item.find(params[:item_id])
    @comment = Comment.create(comment_params)
    respond_to do |format|
      format.html { redirect_to item_path(params[:item_id]) }
      format.json
    end
  end

~ Aktion zerstören diesmal weggelassen ~

  private
  def comment_params
    params.require(:comment).permit(:comment).merge(user_id: current_user.id, item_id: params[:item_id])
  end
end

Erstellen Sie eine neue Jbuilder-Datei

Erstellen Sie eine Jbuilder-Datei. Hier gibt es auch zwei Punkte. Der erste Punkt ist "json.comment_user_id" in der 3. Zeile und "json.item_user_id" in der 7. Zeile. Verzweigen Sie danach die Ansicht, die hinzugefügt werden soll, abhängig davon, ob es sich um einen Verkäufer handelt oder nicht, in der js-Datei. Wenn die Benutzer-ID in der Artikeltabelle und die Benutzer-ID in der Kommentartabelle übereinstimmen, sind Sie der Verkäufer.

Der zweite Punkt ist "json.comment_id" in der ersten Zeile und "json.comment_item_id" in der fünften Zeile. Dies wird im Link \ verwendet, wenn ein Kommentar gelöscht wird. Ersetzen Sie diese im ID-Teil der zu löschenden URL, um sie zum richtigen Link zu machen.

ruby:views/comments/create.json.jbuilder


json.comment_id      @comment.id
json.comment         @comment.comment
json.comment_user_id @comment.user_id
json.name            @comment.user.nickname
json.comment_item_id @comment.item_id
json.item_id         @item.id
json.item_user_id    @item.user_id

Erstellen einer JS-Datei

Es wird länger dauern, aber ich werde den vollständigen Code des vollständigen Codes veröffentlichen.

comment.js


$(function(){
  function buildHTML(comment){
    var html = `<div class="mainShow__box__content__top__commentBox__comments__comment">
                  <div class="profile">
                    <div class="profile__name">
                      ${comment.name}
                    </div>
                    <div class="profile__right">
                      <div class="image">
                        <i class="fas fa-user-circle"></i>
                      </div>
                      <div class="seller_or_buyer">
Verkäufer
                      </div>
                    </div>
                  </div>
                  <div class="comment">
                    <div class="comment__text">
                      ${comment.comment}
                    </div>
                    <div class="comment__bottom">
                      <div class="comment__date">
                        <i class="far fa-clock"></i>
heute
                      </div>
                      <div class="comment__trash">
                        <a item_id="@item" rel="nofollow" data-method="delete" href="/items/${comment.item_id}/comments/${comment.comment_id}"><i class="fa fa-trash"></i>
                        </a>
                      </div>
                    </div>
                  </div>
                </div>`
    return html;
  }

  function buildHTMLother(comment){
    var html = `<div class="mainShow__box__content__top__commentBox__comments__comment--other">
                  <div class="profile">
                    <div class="profile__right">
                      <div class="image">
                        <i class="far fa-user-circle"></i>
                      </div>
                      <div class="seller_or_buyer">
Kunde
                      </div>
                    </div>
                    <div class="profile__name">
                      ${comment.name}
                    </div>
                  </div>
                  <div class="comment">
                    <div class="comment__text">
                      ${comment.comment}
                    </div>
                    <div class="comment__bottom">
                      <div class="date">
                        <i class="far fa-clock"></i>
heute
                      </div>
                      <div class="comment__icon">
                        <div class="flag">
                          <i class="far fa-flag"></i>
                        </div>
                        <div class="trash">
                          <a item_id="@item" rel="nofollow" data-method="delete" href="/items/${comment.item_id}/comments/${comment.comment_id}"><i class="fa fa-trash"></i></a>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>`
    return html;
  }

  $('#comment_form').on ('submit',function(e){
    e.preventDefault();
    var formData = new FormData(this);
    var url = $(this).attr('action');
    $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
    })
    .done(function(data){
      if (data.comment_user_id == data.item_user_id) {
        var html = buildHTML(data);
        $('#comments').append(html);
        $('.text_area').val('');
        $('.comment_btn').prop('disabled', false);
      } else {
        var html = buildHTMLother(data);
        $('#comments').append(html);
        $('.text_area').val('');
        $('.comment_btn').prop('disabled', false);
      }
    })
    .fail(function(){
      alert('error');
    })
  })
});

In der ersten Hälfte wird der HTML-Code der hinzuzufügenden Ansicht beschrieben. Diesmal unterscheidet sich die Ansicht zwischen dem Verkäufer und anderen Personen, und auch das CSS unterscheidet sich geringfügig. Daher haben wir zwei Typen vorbereitet. Wenn es sich um einen Verkäuferkommentar handelt, wird er von der buildHTML-Methode hinzugefügt, und wenn dies nicht der Fall ist, wird er von der buildHTMLother-Methode hinzugefügt. Im HTML-Code ist neben dem Kommentartext und dem Spitznamen auch die ID im Link für die Löschmethode enthalten. Jetzt können Sie die durch asynchrone Kommunikation hinzugefügten Kommentare sofort löschen.

In der zweiten Hälfte werden die spezifischen Ausführungsinhalte der js-Datei geschrieben. Wenn das Verarbeitungsergebnis fertig ist, wird die if-Anweisung verwendet, um bedingt zu verzweigen, ob der Verkäufer ein Verkäufer ist oder nicht.

Unterstützt Turbolinks

Die js-Datei wird möglicherweise nicht normal gelesen, wenn Turbolinks zusammen verwendet werden. Für eine Lösung hierfür war der Artikel einer anderen Person hilfreich. Bis ich diesen Artikel gefunden habe, habe ich nicht gedacht, dass Turbolinks die Ursache sind, also war es ein Augenöffner.

So lösen Sie js, die nur funktionieren, wenn die Seite mit Rails geladen ist @ryico

Der heutige Stapel

Bisher wurde die asynchrone Kommunikation von Ajax erkannt, dass gepostete Kommentardaten von json zurückgegeben werden. Stattdessen habe ich jedoch verstanden, dass die während der Erstellungsaktion erstellte Instanzvariable von jbuilder verarbeitet, in json konvertiert und zurückgegeben wird. Wenn Sie den Datensatz der Elementtabelle wie dieses Mal verwenden möchten, können Sie @item erstellen.

Recommended Posts

Asynchrone Kommunikation im interaktiven Kommentarfeld
Rails Refactoring Geschichte vor Ort gelernt
Buchungsfunktion implementiert durch asynchrone Kommunikation in Rails
Ich habe versucht, die ähnliche Funktion durch asynchrone Kommunikation zu implementieren
[Rails] Ich habe die Validierungsfehlermeldung mit asynchroner Kommunikation implementiert!