[][src]Module mogwai::an_introduction

An introduction to the minimal, obvious, graphical web application interface.

Welcome!

Mogwai is a cute little library for building browser interfaces. It is cognitively small and runtime fast. It acheives these goals by doing very few things, but doing those things well.

The following is a short introduction to the concepts of Mogwai.

Building Gizmos (aka constructing DOM widgets)

Building DOM is one of the main authorship modes in Mogwai. DOM nodes are created using a builder pattern. The builder itself is called a Gizmo and it defines a user interface widget. Gizmos can be run or attached to other Gizmos. The builder pattern looks like this:

extern crate mogwai;
use::mogwai::prelude::*;

div()
  .class("my-div")
  .with(
    a()
      .attribute("href", "http://zyghost.com")
      .text("Schellsan's website")
  )
  .run().unwrap_throw()

The example above would create a DOM node with a link inside it and append it to the document body. It would look like this:

<div class="my-div">
  <a href="http://zyghost.com">Schell's website</a>
</div>

Running Gizmos and removing gizmos

Note that the Gizmo is added to the body automatically with the Gizmo::run function. This run function is special. It hands off the gizmo to be owned by the window - otherwise the gizmo would go out of scope and be dropped. This is important when a gizmo is dropped and all references to its inner DOM node are no longer in scope, that DOM nodeis removed from the DOM.

You may have noticed that we can use the Gizmo::class method to set the class of our div tag, but we use the Gizmo::attribute method to set the href attribute of our a tag. That's because Gizmo::class is a convenience method that simply calls Gizmo::attribute under the hood. Some DOM attributes have these conveniences and others do not. See the documentation for Gizmo for more info. If you don't see a method that you think should be there, I welcome you to add it in a pull request :)

Wiring DOM

Gizmos can be static like the one above, or they can change over time. Gizmos get their dynamic values from the receiving end of a channel called a Receiver<T>. The transmitting end of the channel is called a Transmitter<T>. This should be somewhat familiar if you've ever used a channel in other rust libraries.

Creating a channel is easy using the txrx() function. Then we "wire" it into the Gizmo with one of a number of rx_ flavored Gizmo methods.

Whenever the Transmitter<T> of the channel sends a value, the DOM is updated.

extern crate mogwai;
use::mogwai::prelude::*;

let (tx, rx) = txrx();

div()
  .class("my-div")
  .with(
    a()
      .attribute("href", "https://zyghost.com")
      .rx_text("Schellsan's website", rx)
  )
  .run().unwrap_throw();

tx.send(&"Gizmo's website".into());

Just like previously, this builds a DOM node and appends it to the document body, but this time we've already updated the link's text to "Gizmo's website":

<div class="my-div">
  <a href="http://zyghost.com">Gizmo's website</a>
</div>

Components and more advanced wiring

In bigger applications we often have circular dependencies between buttons, fields and other interface elements. When these complex situations arise we compartmentalize concerns into Components.

Other times we don't need a full component with an update cycle and instead we simply require transmitters, receivers and some handy folds and maps.

JavaScript interoperability

The library itself is a thin layer on top of the web-sys crate which provides raw bindings to tons of browser web APIs. Many of the DOM specific structs, enums and traits come from web-sys. Some of those types are re-exported by Mogwai's prelude. The most important trait to understand for the purposes of this introduction (and for writing web apps in Rust, in general) is the JsCast trait. Its dyn_into and dyn_ref functions are the primary way to cast JavaScript values as specific types.