Phoenix LiveView 是一个基于 Elixir 构建的强大框架,提供了一种无需大量 JavaScript 即可构建实时 Web 界面的创新方法。
但是,与现有的客户端库(例如用于绘图、可视化或渲染的库)集成有时可能会是一个挑战。
在本文中,我们将探讨如何将 Phoenix LiveView 与直接渲染到 DOM 的 Javascript 库集成。
我们将遇到钩子,它允许我们在给定元素的某些生命周期元素上运行Javascript,以及这些钩子如何启用事件流(使用 LiveView 中的 Push_event 和 Javascript 中的 pushEvent)允许客户端和客户端之间进行双向实时通信服务器。
TLDR:在Phoenix LiveView中,您可以使用hooks和push_event来推送数据,并让客户端库处理渲染。
json-view(演示) - 将网页上的 JSON 对象显示为可展开和折叠的树 - 是一些客户端 Javascript 库如何控制对 DOM 的渲染以及与其交互的一个很好的示例.
让我们通过一个示例来了解如何将其与 (LiveView) 服务器提供的 JSON 数据集成。我们将从后端发送一些静态数据来响应事件,但这些数据可以来自任何来源。
以下内容假设您已使用 mix phx.new 设置了 Phoenix 项目,并启用了 LiveView。
有多种方法可以将 Javascript 包合并为页面 Javascript 的一部分。
推荐首选设置超出了本文的范围,但有两种主要方法:
当我们尝试组合这两个库时,存在两种不兼容的渲染模型。
LiveView 遵循 声明性模型 - 您设计视图,确定应显示哪些数据,LiveView 会在底层数据更改时计算出页面的哪些元素需要更改。
它通过在渲染中使用套接字分配来实现这一点:
def render(assigns) do ~H""" <p>Hello <%= @name %></p> """ end
但是,像 json-view 这样的库可以在 命令式模型上工作。我们指定在 DOM 本身布局之外以 Javascript 显示数据所需的步骤:
import jsonview from '@pgrabovets/json-view'; const data = '{"name": "json-view", "version": "1.0.0"}' const tree = jsonview.create(data); jsonview.render(tree, document.querySelector('.tree'));
这两个模型是不一致的。我们看似没有办法匹配两种渲染数据的方法(声明式和命令式),但我们需要像 json-view 这样的库来在客户端渲染丰富的界面。
从根本上来说 - 当服务器提示页面状态更改时,我们需要运行 Javascript 代码。让我们看一下 hooks,它有助于协调这两种渲染模型。
在 LiveView 中,hooks 是在(浏览器)客户端和(LiveView)服务器之间提供双向通信的方式,通信的核心对象是 事件。
钩子在 LiveSocket 中定义,并使用 phx-hook 属性附加到元素。有许多回调 - 但我们将重点关注已安装的回调,因为我们可以通过事件协调其他所有内容。您也可以为其他生命周期事件提供回调 - 查看文档。
在 Mounted 之类的回调中,钩子使用 this.pushEvent 将事件发送到后端,并通过使用 this.handleEvent 为特定事件名称注册处理程序来处理来自服务器的事件。
需要注意的是,每个元素只允许有一个钩子,因此您只需要推理客户端和服务器之间的一个事件流。
记住这些知识 - 让我们定义一个 JsonView 钩子来注册一个事件处理程序,最终调用元素上的 jsonview.render 来渲染数据树。
import { Socket } from 'phoenix'; import jsonview from '@pgrabovets/json-view'; const JsonViewHook = { mounted() { this.handleEvent("render_json", ({ data }) => { this.el.innerHTML = ""; const tree = jsonview.create(data); jsonview.render(tree, this.el); }); } } const liveSocket = new LiveSocket( "/live", Socket, {hooks: { JsonView: JsonViewHook }, ...} ); ...
我们在这几行代码中做了几件事:
要使用此钩子 - 我们只需将带有钩子名称(“JsonView”)的 phx-hook 属性添加到元素中:
<div> <h2> Sending events to the server </h2> <p>We’ll just need to trigger an event from the backend to provide this data. We’ll leave this outside the scope of this article for now - perhaps a button could trigger an event to the backend? - but you could use this.pushEvent from the mounted hook like so:<br> </p> <pre class="brush:php;toolbar:false">mounted() { this.pushEvent("send_json", {}); }
将事件发送到可以使用handle_info处理的LiveView服务器。 LiveView 文档的相关部分涵盖了 this.pushEvent 的更多可能性,包括可以指定处理函数直接处理回复有效负载的场景。
push_event/3 是将事件从 LiveView 推送到浏览器的方式。它可以在任何时候调用 - 包括在挂载时 - 尽管一个好的做法是在发送这些事件之前确保页面及其所有元素处于已知状态。否则 - 您将在页面设置期间默默地删除事件 - 这是导致不可预测性的必然途径!
让我们为可能从客户端收到的事件编写一个handle_event 子句,它将事件推送到客户端:
def render(assigns) do ~H""" <p>Hello <%= @name %></p> """ end
就是这样!这里也有灵活性。在客户端和服务器上使用名称注册事件处理程序标志着事件处理和事件引发方式之间的明确分离。
我们已经看到了客户端和服务器之间集成的一个简单示例。对此的常见扩展是通过使用事件参数和元素属性来将某些更新范围限制到某些元素。这有助于减少不必要的事件和处理程序工作量。
还可以扩展此事件处理,以实现客户端库与后端更紧密的集成。例如,通常这些 Javascript 库会发出更高级别的用户交互事件。我们的库示例 json-view 不会执行此操作,但像 Chart.js 这样的图表库会执行此操作。
但是,从用户交互的角度来看,通常应该避免往返服务器进行处理。通常,任何基于事件的渲染更新都将由渲染库客户端处理。
但是出于其他原因捕获用户活动是一个常见的用例。这包括监控、记录和分析。这些不需要响应,因此钩子内的 PushEvent 非常适合服务器上的此类异步处理。
集成需要控制 DOM 的强大 Javascript 客户端库是创建丰富的动态用户界面的关键部分。并非所有页面更新都需要实时,因此保留 LiveView 提供了一种强大而简单的方法来继续控制其他页面状态。
熟悉 LiveView 挂钩及其相关事件使得将它们与源自服务器的数据集成成为可能。同样重要的是要注意,并非所有用户交互都需要往返服务器,并且当您使用强大的 Javascript 库时,您构建的界面将更加灵活和响应更快。
以上是Phoenix LiveView、钩子和push_event:json_view的详细内容。更多信息请关注PHP中文网其他相关文章!