LiveView
A Crystal abstract class for building server-rendered HTML components with client-side interactivity.
These live views are framework-agnostic. You can use them with any framework and even without a framework at all. They define to_s(io)
so you can either build a string out of them or pipe them to an IO
object (such as your web response).
Installation
-
Add the dependency to your
shard.yml
:dependencies: live_view: github: jgaskins/live_view
-
Run
shards install
Usage
To see a complete example app, check out crystal_live_view_example
require "live_view"
To define a live view, you can inherit from the LiveView
abstract class:
class MyView < LiveView
end
In your HTML layout:
<%= LiveView.javascript_tag %>
Rendering
To define what to render, you can either use the render
macro to define the HTML inline or the template
macro and specify the ECR template to render:
class CurrentTime < LiveView
render "The time is <time>#{Time.now}</time>"
end
Updating the UI
The update(socket : HTTP::WebSocket)
method will update the client with the new UI:
update(socket) # Update with the current state
Hooks
There are 3 hooks:
mount(socket : HTTP::WebSocket)
is called when the client makes a successful websocket connectionunmount(socket : HTTP::WebSocket)
is called when the websocket is closedhandle_event(message : String, data : String, socket : HTTP::WebSocket)
is called when an incoming message is received from the client websocket. Thedata
argument will be aString
in JSON format.
def mount(socket)
end
def unmount(socket)
end
def handle_event(message, data, socket)
case message
when "increment"
update(socket) { @count += 1 }
when "decrement"
update(socket) { @count -= 1 }
end
end
Recurrent UI updates
You can use the every(interval : Time::Span)
method to call update
at that interval. Use the mount(socket : HTTP::WebSocket)
hook to set that up when the view mounts:
class CurrentTime < LiveView
render "The time is <time>#{Time.now}</time>"
def mount(socket)
every(1.second) { update socket }
end
end
Performance
- While the client is connected via WebSocket, the view remains in memory. When the client disconnects, the view is discarded.
- LiveViews which either never mount or which encounter errors (such as
IO::Error
breaking communication) will be discarded. - The client will be given 30-60 seconds to connect after the view has been instantiated, depending on where the system is in the collection cycle.
Contributing
- Fork it (https://github.com/jgaskins/live_view/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Jamie Gaskins - creator and maintainer