認識 Volt,一個用於動態應用程序的有前途的 Ruby 框架

已發表: 2022-03-11

Volt 是一個為數據豐富的應用程序設計的 Ruby 框架。 服務器端和客戶端都是用 Ruby 編寫的(然後使用 OPAL 將其編譯為 JS),因此這允許開發人員編寫非常動態的應用程序,而無需編寫一行 Javascript 代碼。 如果你和我一樣是 Ruby 愛好者,你會喜歡這個框架的。

為了使 Web 應用程序更加動態化,Angular.js、Backbone.js 和 Ember.js 等前端 Javascript 框架已廣受歡迎。 但是,這些框架通常需要後端應用程序才能發揮作用,因此它們與 Ruby on Rails 和 Django 等 Web 框架結合使用。

另一方面,Ruby 框架 Volt 能夠管理後端和動態前端。 由於這兩個功能都緊密集成到其核心中(事實上,Volt 更像是一種 MVVM 架構,利用了數據綁定的優勢),它使開發人員能夠快速構建這些應用程序。

開箱即用的一個非常酷的功能是 Volt 的實時功能。 如果您曾經製作過實時應用程序,那麼您就會知道該過程可能具有挑戰性——您可能實現了 AJAX 輪詢、Web 套接字、服務器發送事件 (SSE),甚至使用了外部服務,從而增加了應用程序的複雜性,甚至產生了額外的成本. 與其他框架不同,Volt 與服務器保持連接(通過 Web 套接字),因此它不會為每個操作發出 Ajax 請求,而是立即將更改推送到所有客戶端。 無需任何配置即可工作。

認識 Volt,一個用於動態應用程序的有前途的 Ruby 框架

使用 Volt 創建聊天應用程序

在這個 Ruby 框架教程中,我將帶您完成使用 Volt 創建實時應用程序的過程,以及比聊天應用程序更好的方式來展示其功能,因為聊天仍然是實時應用程序的第一大用例。

首先,讓我們安裝 Volt 和 MongoDB。 後面的過程就不詳細介紹了:

 gem install volt brew install mongodb
 mkdir -p /data/db

(創建數據庫路徑)

 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 添加到參數中,這樣我們就可以知道哪個已被選擇,並添加一個名為“活動”的類,我們可以稍後對其進行樣式設置。

現在讓我們在控制器中創建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_conversationsend_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 to ''所以我們清空輸入字段。

我們可能還想將該行添加到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 絕對值得一試

儘管 Volt 框架不像大多數流行的 Ruby 框架那樣成熟和健壯,這些框架已經存在多年(目前 Volt 仍處於測試階段),但值得考慮和研究。

如果您有興趣,可以使用這個 Ruby 框架教程來體驗一下 Volt。 密切關注進一步的發展,因為即使在這個開發的早期階段,Volt 看起來也是一個非常有前途的 Ruby 框架。

有很多很酷的新功能正在籌備中,我很確定 Volt 在接下來的幾年裡會變得更加重要,因為越來越多的人開始嘗試它。 由於許多創新功能,許多開發人員可能會愛上 Volt 並將其用於他們的下一個 Ruby 項目。