0.0.3 • Published 8 years ago

pau-flux v0.0.3

Weekly downloads
-
License
MIT
Repository
-
Last release
8 years ago

Pau's Flux Implementation

Yet another Flux implementation, but now with views :)

Build Status Code Climate Test Coverage Issue Count Bower npm

Table of Contents

Basics

Here this framework basic concepts are shown.

Flux architecture

Flux is an application architecture defined by the nice guys at Facebook for client-side web development. The main idea is to avoid the bi-directional MVC data binding in favor of an uni-directional action flow. This is achieved by the definition of three main components:

  • a dispatcher that is in charge to receive all the requests by the other components (called actions) and to trigger the corresponding callbacks;
  • some stores in which the data are stored;
  • some view-controllers that render the contents on the page and trigger actions.

A tipical flux application can be shaped as the following:

Flux architecture

For a complete overview about the flux architecture, you can read this blog post.

Web components

Web components are a collection of standards enabling a developer to wrap markup and styles into custom HTML elements. A typical example of web components is the <video> tag.

Video tag example

As you can see in the picture above, when a video tag is included in a web page, the browser renders a player whose markup is wrapped into a so called shadow DOM. Moreover, the video player can be configured by using the <video> tag attributes.

In the same way, you can create custom and reusable components you can import in a web page and customize by using a predefined API.

For an extensive introduction to web components, please take a look to this css-tricks article.

Putting things together

This project puts together this two concepts in order to create a complete framework for web applications.

Here a web application is seen as a set of custom elements, updated every time the relative store data changes, who trigger actions on the flux dispatcher.

The custom elements view updates are performed by using the good Matt-Esch virtual-dom algorithm inspired by the work of the Facebook team.

Creating a web application

The following example shows how to create a complete web application using this framework. This example is included into the source code in the example/ folder.

In order to run the example, lanch the relative npm script

$ npm run serve

and then navigate to http://localhost:3000 with your browser (use Google Chrome if you don't want to enable Firefox experimental flags).

Structure

You can structure a flux web application as defined below:

myapp/
|
` index.html
` main.js
` elements/
  |
  ` app/
    |
    ` app.html
    ` dispatcher.js
  ` headereditor/
    |
    ` headereditor.html
    ` dispatcher.js

The index.html page contains the import of the main elements.

<html>
  <head>
    <script src="/flux.js"></script>
    <link rel="import" href="/elements/app/app.html">
  </head>
  <body>
    <my-app store="main"></my-app>
    <script src="main.js"></script>
  </body>
</html>

Usually, you don't need to do big things here, all the application relative configuration are defined by the app element.

The main.js script just trigger the initialization action.

(function() {
  F.Dispatcher().dispatch('init');
}());

Defining a new element

A new flux element is defined by a view, implemented into an HTML file, and a dispatcher script.

Below, the view of the header editor is showed.

<script src="dispatcher.js"></script>

<flux-view name="header-editor">

  <template>
    <div>
      <label>Header editor:</label>
      <input type="text" value="{{ header }}" id="headerField"></input>
    </div>
    <div>
      <h4>Instructions:</h4>
      <p>Type a new value into the input box and then change the focus.</p>
    </div>
  </template>

  <script>
F.registerListeners('header-editor', function(ee) {
  var formModel = {};

  ee('headerField::keyup', function(evt) {
    formModel.header = evt.target.value;
  });

  ee('headerField::change', function() {
    var d = F.Dispatcher();
    d.dispatch('setHeader', formModel);
  });

});
  </script>

</flux-view>

The element name is defined by the name attribute of the <flux-view> tag.

The <template> tag defines the markup and the style for the element. From this HTML, the virtual-dom is created and it is compiled by using the Handlebars framework.

In this example, we also register listeners for the DOM generated by the template. In particular, on #headerField changes, the dispatcher setHeader action is dispatched.

Dispatcher actions are defined by the dispatcher.js file, showed below.

(function() {
  var d = F.Dispatcher();
  d.handleAction('setHeader', function(payload) {
    var s = F.Store('main');
    s.getData().header = payload.header;
    s.notify();
  });
}());

An action is registered by the dispatcher handleAction function using the action name and the callback function. The callback function has as arguments the arguments passed to the dispatch method.

When the new element is used, you can specify the store to use using the element store attribute as shown by the app.html element.

<link rel="import" href="/elements/headereditor/headereditor.html">
<script src="dispatcher.js"></script>

<flux-view name="my-app">

  <template>
    <div>
      <h1>{{ header }}</h1>
    </div>
    <div>
      <header-editor store="main"></header-editor>
    </div>
  </template>

</flux-view>