[JAVA] [Rails, JS] So implementieren Sie die asynchrone Anzeige von Kommentaren

In diesem Artikel werde ich erklären, wie die Kommentaranzeige asynchron implementiert wird.

画面収録 2020-10-06 -1.mov.gif

Implementierungsdetails

Was ist ein Kanal?

Was ist ein Kanal?

Ein Kanal ist ein serverseitiger Mechanismus, der sofortige Aktualisierungsfunktionen bietet. Stellen Sie die Datenroute ein und zeigen Sie die gesendeten Daten auf dem Client-Bildschirm an.

Was kannst du mit Channel machen?

Wenn Sie die Datenroute festlegen oder JavaScript schreiben, um die gesendeten Daten anzuzeigen, können die gesendeten Daten asynchron angezeigt werden.

Kanaldatei erstellen

Führen Sie den folgenden Befehl im Terminal aus % rails g channel comment (Geben Sie den Namen der Datei, die Sie erstellen, in "Kommentar" ein.) Es gibt mehrere Dateien, aber dieses Mal werden wir die folgenden zwei Dateien verwenden. app/channel/comment_channel.rb Eine Datei, die Client und Server verbindet.

app/javascript/channels/comment_channel.js Dies ist eine Datei zum Anzeigen der vom Server gesendeten Daten auf dem Client-Bildschirm.

Beschreibung von comment_channel.rb

class MessageChannel < ApplicationCable::Channel
  def subscribed
    stream_from "comment_channel"
  end

  def unsubscribed
  end
end

Sie können den Server und den Client verbinden, indem Sie "stream_from" comment_channel "" schreiben.

Beschreibung von comment_controller.rb

Eine Beschreibung des Controllers. Da die nicht asynchrone Kommentarimplementierungsfunktion bereits abgeschlossen wurde, werden andere Erklärungen als die asynchrone Beschreibung weggelassen.

Beschreiben Sie die Daten, die Sie von der Datenbank an JS übergeben möchten

Die Daten, die ich dieses Mal in JS wiedergeben möchte, lauten wie folgt

Diese drei Informationen müssen vom Controller an JS übergeben werden.

class CommentsController < ApplicationController
  before_action :authenticate_user!
  def create
    @comment = Comment.new(comment_params)
    @item = Item.find(params[:item_id])
    @comments = @item.comments.includes(:user).order('created_at DESC')
    if @comment.valid?
      @comment.save
            ActionCable.server.broadcast  'comment_channel', content: @comment, nickname: @comment.user.nickname, time: @comment.created_at.strftime("%Y/%m/%d %H:%M:%S"), id: @item.id
    else
      render "items/show"
    end
  end

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

In dieser Implementierung wurde nur der folgende Satz hinzugefügt. ActionCable.server.broadcast 'comment_channel', content: @comment, nickname: @comment.user.nickname, time: @comment.created_at.strftime("%Y/%m/%d %H:%M:%S"), id: @item.id

Da in JS "Inhalt", "Benutzer", "Zeit" und "ID" verwendet werden, habe ich sie definiert. content Definiert durch @comment: text, die Textspalte der Kommentartabelle, dh der von Ihnen eingegebene Kommentar. user Der Spitzname des mit @comment verknüpften Benutzers wird abgerufen. (Wir haben eine Assoziation mit Kommentar und Benutzer.) time Die Spalte created_at der Kommentartabelle. Jede Datums- und Uhrzeiteinstellung kann durch Schreiben von "strftime ("% Y /% m /% d% H:% M:% S ")" angezeigt werden. Ich habe auf den folgenden Artikel verwiesen. Ich kann mich nicht an Strftime (Ruby) erinnern item JS muss nur auf der Seite des Elements ausgelöst werden, das Sie gerade anzeigen. Verwenden Sie es also, um dies zu bestimmen.

Beschreibung von comment_channel.rb (JavaScript)

Dieses Mal werden wir es im receive () Teil von app / javascript / channel / comment_channel.js beschreiben.

app/javascript/channels/comment_channel.js


received(data) {
}

Durch Schreiben von "Daten" in () kann der von der Steuerung definierte Wert erhalten werden. "empfangen" bedeutet empfangen. Wenn Sie also die Daten empfangen, führen Sie das darin beschriebene JS aus! Es bedeutet das. Jetzt werde ich JS darin beschreiben!

Schreiben Sie einen bedingten Zweig, damit Kommentare nur auf der aktuell geöffneten Artikelseite angezeigt werden können.

app/javascript/channels/comment_channel.js


//Rufen Sie die URL der aktuell geöffneten Seite ab
let url = window.location.href
//Schrägstrich(/)Extrahieren Sie jeweils Elemente
let param = url.split('/');
//Bei dieser App befindet sich die Element-ID ganz am Ende der URL und wird als paramItem definiert.
let paramItem = param[param.length-1]
//Parameter-ID(Die in der URL enthaltene ID)Vom Controller gesendet`data.id`Bestimmen Sie, ob
if (paramItem == data.id) {}

Die bedingte Verzweigung erfolgt mit der if-Anweisung. Als nächstes werde ich den Inhalt des Prozesses in den bedingten Zweig schreiben. Der zu beschreibende Inhalt ist

--Erstelle ein div-Element

Es ist wie ein Fluss.

Machen Sie ein Div zum Anzeigen

app/javascript/channels/comment_channel.js


    //Holen Sie sich die ID des Div des anzuzeigenden Ortes
    const comments = document.getElementById('comments');
    //Erstellen Sie ein div, das mit einer vorhandenen Ansichtsdatei identisch ist
    const textElement = document.createElement('div');
    textElement.setAttribute('class', "comment-display");
    
    const topElement = document.createElement('div');
    topElement.setAttribute('class', "comment-top");

    const nameElement = document.createElement('div');
    const timeElement = document.createElement('div');

    const bottomElement = document.createElement('div');
    bottomElement.setAttribute('class', "comment-bottom");

Verwenden Sie die Methode createElement, um ein div-Element zu erstellen, und geben Sie jeden erforderlichen Klassennamen mit der Methode setAttribute an.

Die Ansicht zum Anzeigen von Kommentaren ist übrigens wie folgt

  <div id='comments'>
  </div>
  <% @comments.each do |comment| %>
    <div class='comment-display'>
      <div class='comment-top'>
        <div><%= comment.user.nickname %></div>
        <div><%= l comment.created_at %></div>
      </div>
      <div class='comment-bottom'>
        <p><%= comment.text %></p>
      </div>
    </div>
  <% end %>

Ich habe ein div-Element generiert, aber es ist im Browser noch nicht sichtbar. Lassen Sie es uns im Browser anzeigen und eine Eltern-Kind-Beziehung erstellen.

app/javascript/channels/comment_channel.js


      //Zeigen Sie das generierte HTML-Element im Browser an
      comments.insertBefore(textElement, comments.firstElementChild);
      textElement.appendChild(topElement);
      textElement.appendChild(bottomElement);
      topElement.appendChild(nameElement);
      topElement.appendChild(timeElement);

Verwenden Sie die insertBefire-Methode und die appendChild-Methode. Übergeordnetes Element.insertBefore (Element zum Hinzufügen, wo hinzugefügt werden soll) Übergeordnetes Element .appendChild (Element zum Hinzufügen) InsertBefire kann also ein Element an einer beliebigen Stelle einfügen, und appendChild kann ein Element am Ende der übergeordneten Klasse einfügen.

Wenn Sie etwas mehr Details sehen möchten, sehen Sie bitte unten [JavaScript] Unterschied zwischen appendChild und insertBefore

Lassen Sie uns nach dem Erstellen des div-Elements die Informationen anzeigen, die angezeigt werden sollen.

app/javascript/channels/comment_channel.js


      const name = `${data.nickname}`;
      nameElement.innerHTML = name;
      const time = `${data.time}`;
      timeElement.innerHTML = time;
      const text = `<p>${data.content.text}</p>`;
      bottomElement.innerHTML = text;

Die anzuzeigenden Informationen werden in jede Variable eingefügt. Daten sind die Daten für "empfangen (Daten) {}". Dies ist der in der Steuerung definierte Wert. Sie haben "Inhalt", "Spitzname" bzw. "Zeit" definiert. Überschreiben Sie vorhandene Elemente mit innerHTML.

Die Anzeige ist bis zu diesem Punkt vollständig! Bei dieser Rate gibt es jedoch zwei Probleme.

  1. Die Daten werden angezeigt, der Kommentar bleibt jedoch im Kommentareingabefeld.
  2. HTML ist so konzipiert, dass die Schaltfläche standardmäßig nur einmal gedrückt werden kann. Lösen wir das!
Löschen Sie den Kommentar im Kommentareingabefeld nach dem Senden der Daten

app/javascript/channels/comment_channel.js


    const newComment = document.getElementById('comment_text');
    newComment.value='';

Es ist eine Beschreibung, dass die ID des Kommentareingabefelds abgerufen und der Wert dort geleert wird.

Ermöglicht das mehrmalige Drücken der Kommentartaste

app/javascript/channels/comment_channel.js


    const inputElement = document.querySelector('input[name="commit"]');
    inputElement.disabled = false;

Sie können mehrmals darauf klicken, indem Sie das Namensattribut der Schaltfläche "Kommentar" abrufen und als "deaktiviert = falsch" festlegen.

Die Beschreibung ist unten zusammengefasst.

app/javascript/channels/comment_channel.js


import consumer from "./consumer"

consumer.subscriptions.create("CommentChannel", {
  connected() {
  },

  disconnected() {
  },
  //↓ Wenn Sie die Daten erhalten, führen Sie sie aus.
  received(data) {
    let url = window.location.href
    let param = url.split('/');
    let paramItem = param[param.length-1]
    if (paramItem == data.id) {
      const comments = document.getElementById('comments');
      const comment = document.getElementsByClassName('comment-display');
      //Erstellen von Elementen zur Verwendung
      const textElement = document.createElement('div');
      textElement.setAttribute('class', "comment-display");
      const topElement = document.createElement('div');
      topElement.setAttribute('class', "comment-top");
      const nameElement = document.createElement('div');
      const timeElement = document.createElement('div');
      const bottomElement = document.createElement('div');
      bottomElement.setAttribute('class', "comment-bottom");
      //Zeigen Sie das generierte HTML-Element im Browser an
      comments.insertBefore(textElement, comments.firstElementChild);
      textElement.appendChild(topElement);
      textElement.appendChild(bottomElement);
      topElement.appendChild(nameElement);
      topElement.appendChild(timeElement);
      //Generieren Sie den anzuzeigenden Text
      const name = `${data.nickname}`;
      nameElement.innerHTML = name;
      const time = `${data.time}`;
      timeElement.innerHTML = time;
      const text = `<p>${data.content.text}</p>`;
      bottomElement.innerHTML = text;
      //Lassen Sie nach dem Senden eines Kommentars das Kommentarfeld leer
      const newComment = document.getElementById('comment_text');
      newComment.value='';
      //Ermöglicht das mehrmalige Drücken der Taste
      const inputElement = document.querySelector('input[name="commit"]');
      inputElement.disabled = false;
    }
  }
});

abschließend

Ich dachte, es sei abgeschlossen, aber zum Zeitpunkt des Schreibens fand ich eine Reihe von Fehlern und einige unklare Beschreibungen. Ich verstehe, wie wichtig Refactoring ist. Es mag falsche Aussagen geben, aber ich hoffe, es hilft jemandem.

Recommended Posts

[Rails, JS] So implementieren Sie die asynchrone Anzeige von Kommentaren
[Rails] So implementieren Sie Scraping
[Rails] Anzeigen von Datenbankinformationen
[Rails] So implementieren Sie die Sternebewertung
[Rails] So zeigen Sie eine Liste der Beiträge nach Kategorie an
So implementieren Sie eine einzeilige Anzeige von TextView in der Android-Entwicklung
So implementieren Sie Suchfunktionen in Rails
[Rails] So zeigen Sie Fehlermeldungen einzeln an
[Rails] So lassen Sie die Anzeige der Zeichenfolge der link_to-Methode weg
So implementieren Sie Ranking-Funktionen in Rails
So implementieren Sie die Image-Veröffentlichung mithilfe von Schienen
So implementieren Sie die asynchrone Verarbeitung in Outsystems
[Rails] Verwendung von video_tag zum Anzeigen von Videos
[Rails] So implementieren Sie einen Unit-Test eines Modells
So implementieren Sie eine ähnliche Funktion in Rails
Verwendung von JQuery in Rails 6 js.erb
So zeigen Sie das Ergebnis des Ausfüllens des Formulars an
[Rails] So konvertieren Sie die UC-Zeitanzeige in die japanische Zeitanzeige
So deinstallieren Sie Rails
So stellen Sie die Anzeigezeit in Rails auf japanische Zeit ein
So implementieren Sie die Gastanmeldung in 5 Minuten im Rails-Portfolio
So implementieren Sie eine nette Funktion in Ajax mit Rails
[Java] Arten von Kommentaren und wie man sie schreibt
[Rails] So ändern Sie den Spaltennamen der Tabelle
[Rails] So erhalten Sie den Inhalt starker Parameter
Zusammenfassung der Implementierung von Standardargumenten in Java
[Schienen] So zeigen Sie Bilder in der Ansicht an
[Rails] So zeigen Sie die Wettervorhersage der registrierten Adresse auf Japanisch mit OpenWeatherMap an
[Schienen] Wie poste ich Bilder?
[Rails] Verwendung von Enum
[Rails] Verwendung von Enum
Wie schreibe ich einen Java-Kommentar
Wie man Schienenrouten liest
[Java] So zeigen Sie Wingdings an
Verwendung von Rails Join
So beenden Sie den Rails-Server
Wie schreibe ich Rails Seed
[Rails] Verwendung der Validierung
[Schienen] So deaktivieren Sie Turbolinks
[Rails] So verwenden Sie authenticate_user!
[Schienen] Wie man Samen macht
Wie schreibe ich Rails Routing
[Rails] So installieren Sie simple_calendar
[Java] So implementieren Sie Multithreading
[Rails] So installieren Sie reCAPTCHA
[Schienen] Verwendung von Scope
So zeigen Sie das Auswahlfeld von time_select alle 30 Minuten an
So zeigen Sie Diagramme in Ruby on Rails an (LazyHighChart)
[Rails 5] Verwendung von gem gon ~ Übergabe von Variablen von Rails an JS ~
[Schienen] Anzeigen von Informationen, die in der Datenbank gespeichert sind