Sortie de LiveView 0.19.0 : Nouvelles fonctionnalités pour les flux dynamiques, les formulaires et le glisser-déposer avec TodoTrek en open source

2023-05-30 02:35:40

Publié le 29 mai 2023 par Chris McCord


LiveView 0.19.0 est sorti ! Cette version inclut des fonctionnalités de formulaire dynamique tant attendues, de nouvelles primitives de flux et comble l’écart sur ce que vous souhaitiez être possible avec LiveView. Il s’agit de notre dernière version majeure prévue avant LiveView 1.0.

Open source TodoTrek application vitrine

Comme démo et comme promis dans mon Keynote ElixirConfEUje suis en open source TodoTrek application, une application de type Trello qui présente les nouvelles fonctionnalités de flux telles que le glisser-déposer, le défilement infini, les formulaires dynamiques, etc.

Voici TodoTrek en action :

Passons maintenant aux fonctionnalités !

Interface Stream améliorée avec réinitialisations et limites

Les flux dans LiveView 0.18 ont introduit un moyen puissant de gérer de grandes collections sur le client sans stocker la collection dans la mémoire du serveur. Les flux permettent aux développeurs d’ajouter, de préfixer ou d’insérer et de mettre à jour arbitrairement des éléments dans la collection sur l’interface utilisateur. Cela a ouvert la porte à de nombreux cas d’utilisation de type SPA, tels que des chronologies en temps réel et des flux infinis, mais il manquait quelques primitives.

Avec LiveView 0.19, les flux comblent l’écart sur ces primitives. Les flux peuvent être limités sur l’interface utilisateur avec le :limit option. Cela permet au développeur de demander à l’interface utilisateur de conserver les N ou N premiers éléments de la collection lors de l’insertion de nouveaux éléments dans un flux. Ceci est essentiel dans un certain nombre de cas, comme la prévention de la surcharge des clients avec trop de données dans le DOM. Combinées à de nouvelles liaisons de fenêtres, des listes infinies virtualisées peuvent être implémentées sans effort, ce que nous verrons dans un instant.

En plus des limites de flux, les flux prennent désormais également en charge un :reset optionw, qui efface le conteneur de flux sur le client lors de la mise à jour du flux. Ceci est utile dans tous les cas où vous devez effacer les résultats ou réinitialiser une liste, comme la saisie semi-automatique de la recherche ou la pagination traditionnelle.

Avec juste un simple stream(socket, :posts, posts, limit: 10) ou stream(socket, :posts, [], reset: true), vous pouvez désormais effectuer une gestion complexe de la collecte des clients sans avoir à y penser. Mais ce n’est que le début de ce qui est possible.

Flux imbriqués avec glisser-déposer

LiveView 0.19 prend en charge les flux imbriqués, ce qui permet d’implémenter le glisser-déposer en quelques lignes de code seulement. Imaginez un tableau Trello où vous avez des listes nommées contenant des éléments à faire. Vous pouvez faire glisser une goutte réorganiser les listes elles-mêmes ou des tâches dans les listes. Vous pouvez également faire glisser et déposer des tâches dans les listes. Tout cela est désormais possible dans LiveView avec une quantité de code étonnamment petite sur le client et le serveur. Pour le glisser-déposer côté client lui-même, vous pouvez apporter votre propre bibliothèque et l’intégrer à une douzaine de lignes de code. Par exemple, voici le TodoTrek glisser-déposer pour gérer les tâches et les listes :

import Sortable from "../vendor/sortable"
Hooks.Sortable = {
  mounted(){
    let group = this.el.dataset.group
    let sorter = new Sortable(this.el, {
      group: group ? {name: group, pull: true, put: true} : undefined,
      animation: 150,
      dragClass: "drag-item",
      ghostClass: "drag-ghost",
      onEnd: e => {
        let params = {old: e.oldIndex, new: e.newIndex, to: e.to.dataset, ...e.item.dataset}
        this.pushEventTo(this.el, this.el.dataset["drop"] || "reposition", params)
      }
    })
  }
}

Ici, nous importons triable.jspuis câblez-le comme un phx-hook. Désormais, n’importe quel conteneur de flux peut câbler des flux par glisser-déposer avec le balisage suivant :

<div id="todos" phx-update="stream" phx-hook="Sortable">
  ...
div>

Lorsqu’un élément est supprimé, le LiveView recevra un événement “repositionner” avec les nouveaux et anciens index, ainsi que tous les attributs de données existants.

Liaisons de fenêtres pour un défilement infini virtualisé

LiveView 0.19 introduit deux nouveaux phx liaisons pour la gestion des événements de fenêtre – phx-viewport-top et phx-viewport-bottom. Ces événements sont déclenchés lorsque le premier enfant d’un conteneur atteint le haut de la fenêtre ou que le dernier enfant atteint le bas de la fenêtre. La combinaison de ces deux événements avec des limites de flux vous permet d’effectuer un défilement infini “virtuel”, où seul un petit ensemble d’éléments existe dans le DOM, tandis que l’utilisateur expérimente la liste d’un ensemble d’éléments volumineux ou infini. Avant LiveView 0.19, ce type de fonctionnalité obligeait les utilisateurs à échapper à des crochets JavaScript complexes, mais pas plus.

Formulaires dynamiques avec de nouveaux inputs_for

Ajouter et supprimer dynamiquement des entrées avec inputs_for est désormais pris en charge par le rendu des cases à cocher pour les insertions et les suppressions. Les bibliothèques telles que Ecto ou le filtrage de paramètres personnalisé peuvent inspecter les paramètres et gérer les champs ajoutés ou supprimés. Cela peut être combiné avec Ecto.Changeset.cast/3c’est :sort_param et :drop_param options. Par exemple, imaginez un parent Ecto.Schema avec un :emails has_many ou embeds_many association. Pour convertir l’entrée utilisateur à partir d’un fichier imbriqué inputs_foril suffit de configurer les options :

schema "lists" do
  field :title, :string

  embeds_many :emails, EmailNotification, on_replace: :delete do
    field :email, :string
    field :name, :string
  end
end

def changeset(list, attrs) do
  list
  |> cast(attrs, [:title])
  |> cast_embed(:emails,
    with: &email_changeset/2,
    sort_param: :emails_order,
    drop_param: :emails_drop
  )
end

Ici on voit le :sort_param et :drop_param choix en action.

Note: on_replace: :delete sur le has_many et embeds_many est requis lors de l’utilisation de ces options.

Quand Ecto voit le paramètre sort ou drop spécifié du formulaire, il trie les enfants en fonction de l’ordre dans lequel ils apparaissent dans le formulaire, ajoute de nouveaux enfants qu’il n’a pas vus ou supprime les enfants si le paramètre drop lui demande de le faire.

Le balisage d’un tel schéma et d’une telle association ressemblerait à ceci :

<.inputs_for :let={ef} field={@form[:emails]}>
  <input type="hidden" name="list[emails_sort][]" value={ef.index} />
  <.input type="text" field={ef[:email]} placeholder="email" />
  <.input type="text" field={ef[:name]} placeholder="name" />
  <label>
    <input type="checkbox" name="list[emails_drop][]" value={ef.index} class="hidden" />
    delete
  label>
.inputs_for>

<label class="block cursor-pointer">
  <input type="checkbox" name="list[emails_sort][]" class="hidden" />
  add more
label>

Nous avons utilisé inputs_for rendre les entrées pour le :emails association, qui contient une adresse e-mail et une entrée de nom pour chaque enfant. Dans les entrées imbriquées, nous rendons un caché list[emails_sort][] input, qui est défini sur l’index de l’enfant donné. Cela indique à l’opération de conversion d’Ecto comment trier les enfants existants ou où insérer de nouveaux enfants. Ensuite, nous rendons les entrées d’e-mail et de nom comme d’habitude. Ensuite, nous rendons une étiquette contenant le texte “supprimer” et une entrée de case à cocher masquée avec le nom list[emails_drop][], contenant l’index de l’enfant comme valeur. Comme avant, cela indique à Ecto de supprimer l’enfant à cet index lorsque la case est cochée. Enveloppant la case à cocher et le contenu textuel dans une étiquette, tout contenu cliqué dans l’étiquette vérifie et décoche la case.

Enfin, en dehors du inputs_fornous rendons une autre étiquette avec une valeur-moins list[emails_sort][] case à cocher accompagnée du texte “ajouter plus”. Ecto traitera les paramètres de tri inconnus comme de nouveaux enfants et construira un nouvel enfant.

Une grande chose à propos de cette approche est qu’elle permet à la fois à LiveView et aux vues traditionnelles d’utiliser les mêmes primitives de formulaire et de diffusion.

Combler l’écart sur ce qui est possible

Les fonctionnalités de la version 0.19 permettent une implémentation sans effort de toutes sortes de cas d’utilisation auparavant relégués aux applications d’une seule page. Pensez à la messagerie instantanée avec un historique de défilement infini comme Slack, ou à des calendriers sociaux bidirectionnels comme Twitter, ou à des applications Todo comme Trello avec une réorganisation imbriquée par glisser-déposer. C’est maintenant possible sans même avoir à penser aux détails nécessaires sur le client. Cette version nous permet de nous concentrer sur la sortie de LiveView 1.0. Restez à l’écoute!

Bon codage !

–Chris


#Publication #Phoenix #LiveView #Phoenix #Blog
1685409510

Facebook
Twitter
LinkedIn
Pinterest

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.