- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试比我的 previous question regarding tables from RethinkDB in Phoenix 更进一步.
现在我尝试通过 channel 检索它们,以便实时显示表中的新插入内容。
我已经通过handle_in函数插入到表中:
def handle_in("new_person", %{"firstName" => firstName, "lastName" => lastName}, socket) do
broadcast! socket, "new_person", %{firstName: firstName, lastName: lastName}
table("users")
|> insert(%{first_name: firstName, last_name: lastName})
|> RethinkExample.Database.run
{:noreply, socket}
end
在 app.js 中:
dbInsert.on("click", event => { //Detect a click on the dbInsert div (to act as a button)
//Use a module from the channel to create a new person
chan.push("new_person", {firstName: firstName.val(), lastName: lastName.val()});
// Clear the fields once the push has been made
firstName.val("");
lastName.val("");
});
chan.join().receive("ok", chan => {
console.log("Ok");
});
我应该使用哪个函数来处理:
table("users")
|> RethinkExample.Database.run
如果数据现在是 channel 而不是 html,我应该如何呈现数据?我可以使用 HTML+Javascript 渲染插入的人员,但我想要的是从数据库中检索新用户并使用我的其他表结果实时渲染它。
这是我用视觉语言表达的方式:
用户.html.eex
<div class="jumbotron">
<div id="userList">
<%= for %{"first_name" => first_name, "last_name" => last_name} <- @users.data do %>
<p><%= "#{first_name} #{last_name}" %>!</p>
<% end %>
</div>
</div>
<div class="dbOperation">
First name: <input type="text" id="firstName"><br>
Last name: <input type="text" id="lastName"><br>
<div id="dbInsert">Insert</div>
<br>
<div id="userToInsert">User to insert: </div>
</div>
用户 Controller .ex
defmodule RethinkExample.UsersController do
use RethinkExample.Web, :controller
use RethinkDB.Query
def users(conn, _params) do
# List all elements of a table from the database
q = table("users")
# Query for filtering results:
# |> filter(%{last_name: "Palmer"})
|> RethinkExample.Database.run #Run the query through the database
render conn, "users.html", users: q #Render users searched on the users template
end
end
people_channel.ex
defmodule RethinkExample.PeopleChannel do
use Phoenix.Channel
use RethinkDB.Query
#Handles the insert subtopic of people
def join("people:insert", auth_msg, socket) do
{:ok, socket}
end
# handles any other subtopic as the people ID, ie `"people:12"`, `"people:34"`
def join("people:" <> _private_room_id, _auth_msg, socket) do
{:error, %{reason: "unauthorized"}}
end
def handle_in("new_person", %{"firstName" => firstName, "lastName" => lastName}, socket) do
broadcast! socket, "new_person", %{firstName: firstName, lastName: lastName}
query = table("users")
|> insert(%{first_name: firstName, last_name: lastName})
|> RethinkExample.Database.run
new_person = %{"id": hd(query.data["generated_keys"]), "firstName": firstName, "lastName": lastName}
broadcast! socket, "new_person", new_person
{:noreply, socket}
end
def handle_out("new_person", payload, socket) do
push socket, "new_person", payload
{:noreply, socket}
end
end
app.js
import {Socket} from "phoenix"
let App = {
}
export default App
// Fetch fields from HTML through Jquery
let firstName = $("#firstName")
let lastName = $("#lastName")
let dbInsert = $("#dbInsert")
let userToInsert = $("#userToInsert")
let userList = $("#userList")
let socket = new Socket("/ws") //Declare a new socket
socket.connect() //Connect to the created socket
let chan = socket.chan("people:insert", {}) //Assign the people insertion channel to the socket
dbInsert.on("click", event => { //Detect a click on the dbInsert div (to act as a button)
//Use a module from the channel to create a new person
chan.push("new_person", {firstName: firstName.val(), lastName: lastName.val()});
// Clear the fields once the push has been made
firstName.val("");
lastName.val("");
})
chan.on("new_person", payload => {
userToInsert.append(`<br/>[${Date()}] ${payload.firstName} ${payload.lastName}`);
console.log("New Person", payload);
userList.append(`<br><p> ${payload.firstName} ${payload.lastName}!</p>`);
})
chan.join().receive("ok", chan => {
console.log("Ok");
})
最佳答案
您的 channel 中需要有一个 handle_out
函数来监听插入。如果您使用 broadcast_from!
那么发件人将被排除在外,如果您使用 broadcast!
那么发件人也会收到消息。
将以下内容添加到您的 channel :
def handle_out("new_person", payload, socket) do
push socket, "new_person", payload
{:noreply, socket}
end
以及您的 JS 客户端的以下内容:
chan.on("new_person", payload => {
console.log("New Person", payload);
});
channel 文档位于 http://www.phoenixframework.org/docs/channels
编辑
在 Rethink 中插入记录时 - 输出如下所示:
%RethinkDB.Record{data: %{"deleted" => 0, "errors" => 0,
"generated_keys" => ["7136199a-564b-42af-ad49-5c84cbd5b3e7"],
"inserted" => 1, "replaced" => 0, "skipped" => 0, "unchanged" => 0}}
我们知道您从 rethink 查询返回的数据如下所示:
{"first_name" => "John",
"id" => "57c5d0d2-5285-4a24-a999-8bb7e2081661", "last_name" => "Smith"},
因此 - 为了将新记录广播到浏览器,我们希望复制此数据结构,因此如果您将 handle_in
函数更改为:
def handle_in("new_person", %{"firstName" => first_name, "lastName" => last_name}, socket) do
query = table("users")
|> insert(%{first_name: firstName, last_name: lastName})
|> RethinkExample.Database.run
new_person = %{"id": hd(query.data["generated_keys"]), "first_name": first_name, "last_name": last_name}
broadcast! socket, "new_person", new_person
{:noreply, socket}
end
然后 - 如果您按照上述步骤使用 handle_out
和 chat.on
,那么您将在 JavaScript 控制台中看到该人已注销。从那里 - 您可以使用 Javascript 将其附加到您的 DOM。
关于real-time - 在Phoenix框架中实时显示rethinkDB表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31536670/
我正在尝试从模板中的列表( )中提取值,但出现此错误: lists in Phoenix.HTML and templates may only contain integers represent
我正在阅读 Programming Phoenix 这本书,一切都很好,直到第 44 页要求我重新启动 Phoenix 服务器。 我用双 Ctrl + C 杀死了当前服务器,但是当我尝试再次运行 mi
我的应用程序和 api json 请求以及常规 html 都可以工作。我的路由器.ex defmodule MyApp.Router do use MyApp.Web, :router pip
我想在模板中将对象呈现为 JSON。我试过: 但是我得到一个错误 protocol Phoenix.HTML.Safe not implemented for %Ecto.Changeset{...
在 phoenix 框架的 View 中,在 div 元素内生成两个 span 元素的方法是什么? 最佳答案 为了做到这一点,可以只使用一个数组并将其作为 div 标签的值传递给内部,如下所示: de
我从 Rails 迁移,并希望这能在我的模板中工作? hello world 似乎没有一个条件得到呈现。如何实现这一目标? 谢
完成示例指南。本章中详细介绍的内容在我的应用程序中不起作用。看起来很简单的事情。我有一个视频模型: defmodule Rumbl.Video do use Rumbl.Web, :model
完成示例指南。本章中详细介绍的内容在我的应用程序中不起作用。看起来很简单的事情。我有一个视频模型: defmodule Rumbl.Video do use Rumbl.Web, :model
通过可选“inputs_for”输入的 Phoenix 嵌套表单导致 Controller 中的 map 无法通过验证。例如,一个帖子有评论。如果我想在创建帖子时为帖子添加评论,嵌套表单将如下所示:
我正在尝试在应用程序中实现不同的语言。所以我所做的是在 Session 的 db 中创建了 lang 变量,它保留了当前选择的语言。 问题是我正在通过更新操作调用和更新值: def update(co
我想在我的网站上实现一个典型的“记住我”功能,它需要一种方法来创建在遥远的 future 过期的 cookie。有没有办法在 Phoenix Framework 中创建它们? 最佳答案 只要给 coo
我正在制作一个多站点应用程序。我想在测试 Controller 之前在连接上设置请求主机。在 Rails 中,我们可以使用 before :each do request.env["HTTP_RE
我知道我可以通过包含以下内容来更新实时取景: if connected?(socket), do: :timer.send_interval(10000, self(), :click) 但是,有没有
Ruby on Rails 带有终端命令 rake routes . Phoenix 有类似的吗? 最佳答案 命令是 $ mix phoenix.routes 关于phoenix-framework
我正在尝试使用 addict包以在我的项目中进行身份验证,但是每当我尝试执行操作(注册、登录...)时,我的 POST 都会出现 CrossDomain 错误。 我已经尝试添加 cors_plug包来
我在 Phoenix 项目,和mix ecto.create , mix ecto.migrate , 和 mix ecto.drop都发出相同的错误: $ mix ecto.drop ==> tzd
在我的帖子模型上,我实现了一个简单的验证 def changeset(model, params \\ :empty) do model |> cast(params, @requ
这主要是为了测试目的,但是我怎样才能在 Heroku 上实现与 mix ecto.reset 相同的效果。这样的命令导致 FATAL: permission denied for database "
我们的 Web 应用程序目前在 C# 中运行在 Windows 和 IIS 上。我们严重依赖此环境中包含的 Windows 身份验证方案。启用 Windows 身份验证后,我们可以检测连接用户的身份,
在我的 Phoenix 应用程序中,我想对单个记录运行 get_by() Ecto 查询 - 但是,我要搜索的字段之一应该评估为 nil ,但 Phoenix/Ecto 禁止使用 nil 作为比较运算
我是一名优秀的程序员,十分优秀!