本文概述
- 使用伏特创建聊天应用程序
- 入门
- 属性和CSS
- 总结实时通知
- 伏特绝对值得一试
为了使Web应用程序更具动态性, 前端Javascript框架(例如Angular.js, Backbone.js和Ember.js)获得了很大的普及。但是, 这些框架通常需要后端应用程序才能有用, 因此它们与Ruby on Rails和Django等Web框架结合使用。
另一方面, Ruby框架Volt能够管理后端和动态前端。由于这两种功能都紧密集成到其核心中(实际上, Volt更像是MVVM体系结构, 利用了数据绑定的优势), 因此它使开发人员能够快速构建这些应用程序。
开箱即用的一项非常酷的功能是Volt的实时功能。如果你曾经制作过实时应用程序, 那么你就会知道该过程可能会很困难–你可能实施了AJAX轮询, Web套接字, 服务器发送事件(SSE)甚至使用了外部服务, 这增加了应用程序的复杂性, 甚至产生了额外的成本。与其他框架不同, Volt(通过Web套接字)保持与服务器的连接保持活动状态, 因此, 它无需为每个操作发出Ajax请求, 而是立即将更改推送给所有客户端。无需配置即可工作。
文章图片
使用伏特创建聊天应用程序 在本Ruby框架教程中, 我将带你完成使用Volt创建实时应用程序的过程, 以及比聊天应用程序更好的方法来展示其功能, 因为聊天仍然是实时应用程序的第一个用例。
首先, 让我们安装Volt和MongoDB。后面的过程将不再详细介绍:
gem install volt
brew install mongodb
mkdir -p /data/db
(创建dbpath)
chown `id -u` /data/db (change the owner to have the proper dbpath permissions)
现在, 我们准备创建我们的第一个应用程序, 称之为” 聊天” 。我们可以通过以下几行轻松地做到这一点:
volt new chat
cd chat
文档结构与Rails有一些相似之处。 Rails用户会注意到的主要区别是, 应用程序内部有一个额外的文件夹, 其中包含资产, 控制器, 模型和视图等其余文件夹, 此额外文件夹是” 组件” 。
组件是应用程序的隔离部分。组件内的所有页面都呈现出来而无需重新加载页面, 因为该组件的所有文件都已加载了初始的http请求, 因此, 如果我们访问其他组件的页面, 则会发出新的http请求, 并且页面将被” 重新加载” ‘ 。在此示例中, 我们使用默认组件” main” 。
让我们通过在控制台中执行” volt server” 命令来启动服务器, 并通过导航至localhost:3000来查看其在浏览器中的外观:
volt server
另外, 不要忘记在控制台中启动MongoDB:
mongod
我们可以注意到, Volt带有许多默认页面, 包括” 首页” 和” 关于” 。这些可以立即进行定制。
另一点值得一提的是页面右上方的登录按钮。 Volt通过” volt-user-templates” gem将” 用户” 功能集成到框架中, 该功能提供了一种开箱即用的方式来注册和验证用户。
入门 现在, 让我们开始开发我们的应用程序。首先, 我们不需要” 关于” 页面, 因此我们可以继续删除以下内容:app / main / views / main / about.html文件, app / main / controllers / main_controller.rb中的about操作, 请在app / main / config / routes.rb中删除/ about路由, 并在app / main / views / main / main.html中删除导航链接。
<
ul class="nav nav-pills pull-right">
<
:nav href="http://www.srcmini.com/" text="Home" />
<
:user-templates:menu />
<
/ul>
现在开始做生意, 首先列出所有注册用户:
<
:Body>
<
h1>
Home<
/h1>
<
div class="row">
<
div class="col-md-4">
{{ _users.each do |user| }}
<
div class="contact">
{{user._name}}
<
/div>
{{ end }}
<
/div>
<
/div>
现在, 所有注册用户都在主页中列出。请注意, {{}}中编写的代码是要执行的Ruby代码。这样, 我们可以遍历用户集合并打印出每个用户集合。
你可能已经注意到, “ 用户” 是存储所有用户的集合的名称;要记住的一点是, 访问属性时要在属性名称前加上下划线” ” 。为此, 我们首先需要在main_controller.rb文件顶部添加一行代码:
model :store
Volt带有可从控制器访问的多个收集模型, 并且每个模型都将信息存储在不同的位置。商店收集模型将数据存储在数据存储中, 在这里我们指定使用该控制器的控制器(目前唯一支持的数据存储是MongoDB)。让我们创建几个用户来查看外观。
目前, 此页面没有什么令人兴奋的, 我们只是列出注册用户。现在, 我希望能够选择要向其发送消息的用户, 从列表中删除当前登录用户的名称(因为他不应该向自己发送消息), 仅将列表显示给已认证的用户用户, 并向未经身份验证的用户显示” 着陆” 页面:
<
:Body>
<
h1>
Home<
/h1>
{{ if Volt.user }}
<
div class="row">
<
div class="col-md-4">
{{ _users.each do |user| }}
{{ if user._id != Volt.user._id }}
<
div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)">
{{user._name}}
<
/div>
{{ end }}
{{ end }}
<
/div>
<
/div>
{{ else }}
<
p>
This is a sample application built with Volt to demonstrate its real-time capabilities. Please log in to access it.<
/p>
{{ end }}
Volt.user返回当前(已登录)用户或nil。
通过e-click属性, 我们可以从控制器中选择一个方法, 该方法将在单击该元素时被调用。
属性和CSS 实际上, 所有” e” 属性在Volt中都是事件绑定器, 因此, 例如, 我们可以将e-submit添加到表单中以选择将在控制器上调用的操作。我们将在参数中添加” 选定的” 用户ID, 以便我们知道已选择了哪个ID, 并添加了一个名为” 活动” 的类, 以后可以对其进行样式设置。
现在, 让我们在控制器中创建select_conversation方法:
def select_conversation(user)
params._user_id = user._id
end
就是这样–如果你再次签出该页面, 则可以看到每次单击用户名时URL都会更改。另外, ” active” 类已添加到该元素, 因此让我们添加一些CSS以使其可见(我将继续为以后添加的项目添加CSS):
.conversation{
form{
input{
margin: 10px 0 5px 0;
}
}
}
.contact{
width:100%;
padding:5px;
margin: 4px 0;
font-size:15px;
cursor:pointer;
&
:hover{
background-color: #FAFAFA;
}
&
.active{
background-color: #337ab7;
color: #FFF;
}
.badge{
background-color: #900;
}
}
.message{
max-width: 80%;
padding:10px 15px;
margin: 5px 0;
background-color: #FEFEFE;
border: 1px solid #E7E7E7;
border-radius: 5px;
float: left;
clear:both;
&
.sent{
background-color: #E4F3DB;
border: 1px solid #B7D0A7;
float: right;
}
p{
margin:0;
}
}
现在, 让我们在右侧创建一个表单, 向每个用户发送消息:
<
:Body>
<
h1>
Home<
/h1>
{{ if Volt.user }}
<
div class="row">
<
div class="col-md-4">
{{ _users.each do |user| }}
{{ if user._id != Volt.user._id }}
<
div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)">
{{user._name}}
<
/div>
{{ end }}
{{ end }}
<
/div>
{{ if params._user_id }}
<
div class="col-md-8 well conversation">
{{ current_conversation.each do |message| }}
<
div class="message {{ if message._sender_id == Volt.user._id }} sent {{ end }}">
<
p>
{{ message._text }}<
/p>
<
/div>
{{ end }}
{{ if current_conversation.count == 0 }}
<
p>
You have no messages yet. Start chatting!<
/p>
{{ else }}
<
div class="clearfix">
<
/div>
{{ end }}
<
form e-submit="send_message" role="form">
<
div class="form-group">
<
input class="form-control" type="text" placeholder="Write a message" value="http://www.srcmini.com/{{ page._new_message }}" />
<
button type="submit" class="btn btn-primary pull-right">
Submit<
/button>
<
/div>
<
/form>
<
/div>
{{ end }}
<
/div>
{{ else }}
<
p>
This is a sample application built with Volt to demonstrate its real-time capabilities. Please log in to access it.<
/p>
{{ end }}
首先, 我们在显示表单之前先检查是否有选中的用户, 然后我们将通过稍后将要定义的控制器中的方法显示当前对话(与所选用户的对话)中的所有消息, 在底部, 我们正在显示用于发送新消息的表单。
请注意, 输入值是我们在页面集合模型上创建的属性, 因为我们不希望将其存储在数据存储区中。现在, 让我们在控制器中定义current_conversation和send_message方法:
def send_message
unless page._new_message.strip.empty?
_messages <
<
{ sender_id: Volt.user._id, receiver_id: params._user_id, text: page._new_message }
page._new_message = ''
end
end
def current_conversation
_messages.find({ "$or" =>
[{ sender_id: Volt.user._id, receiver_id: params._user_id }, { sender_id: params._user_id, receiver_id: Volt.user._id }] })
end
在send_message方法中, 如果消息不为空(我们正在检查内联, 因此我们现在不必打扰验证), 则向集合中添加新消息, 然后将页面._new_message设置为” , 我们清空输入字段。
我们可能还希望将该行添加到select_conversation方法的末尾。当前的对话方法仅查询_messages集合以获取所选用户和当前用户之间的消息。
总结实时通知 最后, 我想拥有某种通知系统, 以便用户可以看到其他用户何时向他们发送消息。
让我们添加一个名为_notifications的新集合, 并在每条消息发送后创建一个新集合:
def send_message
unless page._new_message.strip.empty?
_messages <
<
{ sender_id: Volt.user._id, receiver_id: params._user_id, text: page._new_message }
_notifications <
<
{ sender_id: Volt.user._id, receiver_id: params._user_id }
page._new_message = ''
end
end
def select_conversation(user)
params._user_id = user._id
unread_notifications_from(user).then do |results|
results.each do |notification|
_notifications.delete(notification)
end
end
page._new_message = ''
end
def unread_notifications_from(user)
_notifications.find({ sender_id: user._id, receiver_id: Volt.user._id })
end
另外, 我们需要在用户选择对话并查看新消息后删除通知, 因此我将该部分添加到select_conversation方法中。
让我们在用户名旁边添加一个通知计数器:
<
div class="contact {{ if params._user_id == user._id }} active {{ end }}" e-click="select_conversation(user)">
{{user._name}}
{{ if unread_notifications_from(user).count >
0 }}
<
span class="badge">
{{ unread_notifications_from(user).count }}
<
/span>
{{ end }}
<
/div>
现在该应用程序已准备就绪, 你可以打开几个浏览器并开始测试Volt的实时功能。
伏特绝对值得一试 尽管Volt框架不像已经流行了很多年的大多数流行的Ruby框架(目前Volt仍处于beta版)那样成熟和健壮, 但还是值得考虑和研究的。
如果你有兴趣, 请使用此Ruby框架教程将Volt试一下。密切关注进一步的开发, 因为即使在开发的初期, Volt仍然看起来是非常有前途的Ruby框架。
管道中有许多很酷的新功能, 我敢肯定, 随着越来越多的人开始尝试Volt, Volt在接下来的几年中将变得越来越重要。由于具有许多创新功能, 许多开发人员可能会爱上Volt并将其用于下一个Ruby项目。
推荐阅读
- 介绍Battlescripts(机器人,飞船,混乱!)
- React.js查看状态管理教程
- 高级Java类教程(类重载指南)
- JavaScript的Promise(带有示例的教程)
- Android平板电脑的布局
- Android(如何为图标创建通知徽章())
- Spring 5 MVC Angular 5 App投掷404错误
- SpringBoot + Mybatis + MySQL,java.lang.IllegalStateException(无法加载ApplicationContext)
- 如何直接从Android应用程序发送电子邮件而不显示设备的默认电子邮件形式()