Ovto::Component

Your app must have a View class, a subclass of Ovto::Component.

'render' method

render is the only method you need to define in the View class. It must take the global app state as a keyword argument state:.

  class View < Ovto::Component
    def render(state:)
      o 'div' do
        o 'h1', 'Your todos'
        o 'ul' do
          state.todos.each do |todo|
            o 'li', todo.title
          end
        end
      end
    end
  end

MoreThanOneNode error

If you missed the surrounding 'div' tag, Ovto raises an MoreThanOneNode error. render must create a single DOM node.

    def render(state:)
      o 'h1', 'Your todos'
      o 'ul' do
        state.todos.each do |todo|
          o 'li', todo.title
        end
      end
    end

#=> $MoreThanOneNode {name: "MoreThanOneNode", message: "MyApp::View#render must generate a single DOM node. Please wrap the tags with a 'div' or something.", stack: "MoreThanOneNode: MyApp::View#render must generate …opbox/proj/ovto/example/tutorial/app.js:22887:18)"}

The 'o' method

Ovto::Component#o describes your app's view. For example:

o 'div'
#=> <div></div>

o 'div', 'Hello.'
#=> <div>Hello.</div>

You can pass attributes with a Hash.

o 'div', class: 'main', 'Hello.'
#=> <div class='main'>Hello.</div>

There are shorthand notations for classes and ids.

o 'div.main'
#=> <div class='main'>Hello.</div>

o 'div#main'
#=> <div id='main'>Hello.</div>

You can also give a block to specify its content.

o 'div' do
  'Hello.'
end
#=> <div>Hello.</div>

o 'div' do
  o 'h1', 'Hello.'
end
#=> <div><h1>Hello.</h1></div>

Special attribute: style

There are some special keys for the attributes Hash. style: key takes a hash as its value and specifies styles of the tag.

o 'div', style: {color: 'red'}, 'Hello.'
#=> <div style='color: red;'>Hello.</div>

Special attribute: onxx

An attribute starts with "on" specifies an event handler.

For example:

o 'input', {
  type: 'button',
  onclick: ->(e){ p e.target.value },
  value: 'Hello.'
}

The argument e is an instance of Opal::Native and wraps the JavaScript event object. You can get the input value with e.target.value here.

Lifecycle events

There are special events oncreate, onupdate, onremove, ondestroy.

https://github.com/hyperapp/hyperapp#lifecycle-events

Special attribute: key

https://github.com/hyperapp/hyperapp#keys

Sub components

o can take another component class to render.

  class TodoList < Ovto::Component
    def render(todos:)
      o 'ul' do
        todos.each do |todo|
          o 'li', todo.title
        end
      end
    end
  end

  class View < Ovto::Component
    def render(state:)
      o 'div' do
        o 'h1', 'Your todos'
        o TodoList, todos: state.todos
      end
    end
  end

Note that you cannot call o more than once in the render method of sub components too. In other words, sub component must yield a single DOM element.

Text node

Sometimes you may want to create a text node.

#=> <div>Age: <span class='age'>12</a></div>

o generates a text node when 'text' is specified as tag name. The above HTML could be described like this.

o 'div' do
  o 'text', 'Age:'
  o 'span', '12'
end

results matching ""

    No results matching ""