Next step: the release of THE TodoMVC implementation.
Add opal-praha to your Gemfile
with a reference to the Github source.
gem 'opal-praha'
If you're compiling opal in a static application, make sure to require bundler first.
require 'bundler'
Bundler.require
Client side models.
class Book < Praha::Model
attributes :title, :author
end
book = Book.new(title: 'My awesome book', author: 'Bob')
book.title = 'Bob: A story of awesome'
Attributes can be defined on subclasses using attributes
. This simply defines
a getter/setter method using attr_accessor
. You can override either method as
expected:
class Book < Praha::Model
attributes :title, :release_date
# If date is a string, then we need to parse it
def release_date=(date)
date = Date.parse(date) if String === date
@release_date = date
end
end
book = Book.new(:release_date => '2013-1-10')
book.release_date
# => #<Date: 2013-1-10>
Praha::View
is a simple wrapper class around a dom element representing a
view of some model (or models). A view's element
is dynamically created when
first accessed. View.element
can be used to specify a dom selector to find
the view in the dom.
Assuming the given html:
<body>
<div id="foo">
<span>Hi</span>
</div>
</body>
We can create our view like so:
class MyView < Praha::View
element '#foo'
end
MyView.new.element
# => #<Element: [<div id="foo">]>
A real, existing, element can also be passed into the class method:
class MyView < Praha::View
# Instances of this view will have the document as an element
element Document
end
Views can have parents. If a child view is created, then the dom selector is only searched inside the parents element.
A View
will render as a div tag, by default, with no classes (unless an
element selector is defined). Both these can be overriden inside your view
subclass.
class NavigationView < Praha::View
def tag_name
:ul
end
def class_name
"navbar navbar-blue"
end
end
Views have a placeholder render
method, that doesnt do anything by default.
This is the place to put rendering logic.
class MyView < Praha::View
def render
element.html = 'Welcome to my rubyicious page'
end
end
view = MyView.new
view.render
view.element
# => '<div>Welcome to my rubyicious page</div>'
When an element is created, defined events can be added to it. When a view is destroyed, these event handlers are then removed.
In Praha, event listening is done directly in the HTML or HAML
.view
%input.toggle(opal-click){type: "checkbox", checked: @todo.completed}
%label.editable(opal-dblclick)= @todo.title
%button.destroy(opal-click)
.form
%input.edit(opal-focusout="finish_editing" opal-press-enter="finish_editing"){value: @todo.title}
You can also override create_element
if you wish to have any custom element
creation behaviour.
For example, a subview that is created from a parent element
class NavigationView < Praha::View
def initialize(parent, selector)
@parent, @selector = parent, selector
end
def create_element
@parent.find(@selector)
end
end
Assuming we have the html:
<div id="header">
<img id="logo" src="logo.png" />
<ul class="navigation">
<li>Homepage</li>
</ul>
</div>
We can use the navigation view like this:
@header = Element.find '#header'
nav_view = NavigationView.new @header, '.navigation'
nav_view.element
# => [<ul class="navigation">]
Praha::Router
is a simple router that watches for hashchange events.
router = Praha::Router.new
router.route("/users") do
puts "need to show all users"
end
router.route("/users/:id") do |params|
puts "need to show user: #{ params[:id] }"
end
# visit "example.com/#/users"
# visit "example.com/#/users/3"
# visit "example.com/#/users/5"
# => "need to show all users"
# => need to show user: 3
# => need to show user: 5
Adds KVO style attribute observing.
class MyObject
include Praha::Observable
attr_accessor :name
attr_reader :age
def age=(age)
@age = age + 10
end
end
obj = MyObject.new
obj.add_observer(:name) { |new_val| puts "name changed to #{new_val}" }
obj.add_observer(:age) { |new_age| puts "age changed to #{new_age}" }
obj.name = "bob"
obj.age = 42
# => "name changed to bob"
# => "age changed to 52"
class MyArray
include Praha::ObservableArray
end
array = MyArray.new
array.add_observer(:content) { |content| puts "content is now #{content}" }
array.add_observer(:size) { |size| puts "size is now #{size}" }
array << :foo
array << :bar
# => content is now [:foo]
# => size is now 1
# => content is now [:bar]
# => size is now 2
- Support older browsers which do not support onhashchange.
- Support not-hash style routes with HTML5 routing.
MIT