个性化阅读
专注于IT技术分析

认识Volt,这是一个针对动态应用程序的有前途的Ruby框架

本文概述

Volt是一个为数据丰富的应用程序设计的Ruby框架。服务器端和客户端都使用Ruby编写(然后使用OPAL编译为JS), 因此这使开发人员可以编写非常动态的应用程序, 而不必编写一行Javascript代码。如果你是像我这样的Ruby粉丝, 那么你会喜欢这个框架的。

为了使Web应用程序更具动态性, 前端Javascript框架(例如Angular.js, Backbone.js和Ember.js)获得了很大的普及。但是, 这些框架通常需要后端应用程序才能有用, 因此它们与Ruby on Rails和Django等Web框架结合使用。

另一方面, Ruby框架Volt能够管理后端和动态前端。由于这两种功能都紧密集成到其核心中(实际上, Volt更像是MVVM体系结构, 利用了数据绑定的优势), 因此它使开发人员能够快速构建这些应用程序。

开箱即用的一项非常酷的功能是Volt的实时功能。如果你曾经制作过实时应用程序, 那么你就会知道该过程可能会很困难–你可能实施了AJAX轮询, Web套接字, 服务器发送事件(SSE)甚至使用了外部服务, 这增加了应用程序的复杂性, 甚至产生了额外的成本。与其他框架不同, Volt(通过Web套接字)保持与服务器的连接保持活动状态, 因此, 它无需为每个操作发出Ajax请求, 而是立即将更改推送给所有客户端。无需配置即可工作。

认识Volt,这是一个针对动态应用程序的有前途的Ruby框架

使用伏特创建聊天应用程序

在本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="/" 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="{{ 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项目。

赞(0)
未经允许不得转载:srcmini » 认识Volt,这是一个针对动态应用程序的有前途的Ruby框架

评论 抢沙发

评论前必须登录!