the industrial

ブログと言うより自分のためのメモ以外の何モノでもないです。でも読んでくださってありがとうございます。

ゾンビワールドへようこそ

ゾンビーワールドへようこそ(字幕版)

ボーイスカウトの男の子三人が、ゾンビだらけになった町からボーイスカウトの技術を駆使して脱出するべく奔走する

ちょっと青春要素も入ったゾンビ映画

あまり期待していなかったのだけど、なかなかおもしろかった

ウォーキングゾンビランド(字幕版)

しかし、直前に観ようとしたウォーキングゾンビランドという映画が

ビックリするくらい面白くなかった

数年ぶりに映画を途中で観るのをやめた

エスター

エスター (字幕版)

この娘、どこかが変だ

というキャッチフレーズでおなじみのホラー、もとい、サスペンス映画

養子で迎え入れた少女エスターは、どこかオカシイ子だった的な

エスターの正体は考えつかなかった

ドキドキはしたので満足だけど、全体的によくあるサスペンス映画だったので、観終わった後の印象は薄かったな

2016年映画個人ランキング

サウスポー(字幕版)

昨年はコチラ

omiend.hatenablog.jp

サウスポー

ピエロがお前を嘲笑う

君の名は

シン・ゴジラ

アバウト・タイム

チェイス

KINGSGLAIVE FINAL FANTASY XV

10クローバーフィールドレーン

アイ アム ア ヒーロー

ぼくとアールと彼女のさよなら

クロニクル

レヴェナント

モンスターズ

スター・ウォーズ フォースの覚醒

言の葉の庭

宇宙人ポール

〜〜〜〜ここから順位はテキトウ〜〜〜〜

アナと雪の女王

ズートピア

怪盗グルー

デッドプール

スコット・ピルグリム

オデッセイ

ミニオン

アベンジャーズ エイジ・オブ・ウルトロン

キャプテン・アメリカ シビル・ウォー

BATMAN V SUPERMAN

ヘイトフルエイト

フォックスキャッチャー

エクスペンダブルズ3

デビル

キャビン

エンジェルウォーズ

インシディアス

リセット

ロックンローラ

ローグネイション

アップサイドダウン - 重力の恋びと

アタック ザ ブロック

ハウンター

BLACK BOX 〜記憶の罠〜

ヴィジット

バンクジョブ

ミッドナイト・ミート・トレイン

デイ オブ ザ デッド

ヘンゼルとグレーテル

ロボコップ

バタリアン

automata

白雪姫と鏡の女王

桐島、部活やめるってよ

秒速5センチメートル

雲の向こう、約束の場所

ほしのこえ

アンナ・カレーニナ

幸せの1ページ

スター・ウォーズ ジェダイの帰還(エピソード6)

スター・ウォーズ 帝国の逆襲(エピソード5)

不思議な岬の物語

ウルトラヴァイオレット

デビル

デビル (字幕版)

ブラピの映画ではなく、M・N・シャマラン監督が制作に関わったホラー映画。

キャビンと続けて観たのだけど、これも面白かった。

直近で観たヴィジットが強烈に救い用の無い話だったので、これもそうだったりするのかなーなんて思ってたのだけど全然そんなことなかった。

何処となくサインにも似たような雰囲気に仕上がっていて良かった。

キャビン

キャビン(字幕版)

最近ホラー映画ばかり観ているのだけど、これは傑作の部類に入るのではないかと思うくらい面白かった。

前半はいつもどおりワカモノ達が森の中の小屋でウンタラカンタラして、一人ひとり惨殺されていく感じなのだけど、それを裏で操っている謎の組織が居て、後半はマッタク別物の映画になってるとか。

「ここでおっpい出すことを観客が望んでいるんだよ→観客って誰だ?」みたいなメタ表現があったりするのも楽しい。

クトゥルフ的な流れも好き。

Riot.js を利用してTODOアプリケーション構築のハンズオンを作成しました #riotjs

Riot.js Advent Calendar 2016 の2日目!

1日目はkuwahara_jsngさんの「今年1年真剣にRiot.jsと付き合ってきたので振り返ってみた」です。

さて、ついにv3がリリースされたRiot.jsですが、実は以前、社内向けに作ったハンズオンがあるので、Riot.js Advent Calendar 2016の場をお借りして紹介させていただきたいと思います。

ただ、バージョンは2.6時点のものですのでご了承下さい。

v3版も、いずれ近いうちに!!!

デモ

http://omiend.github.io/riotjs_todo/

はじめに

Riot.jsとは

関連するHTMLとJavaScriptを結合し、再利用可能なコンポーネントとしてまとめたカスタムタグを利用してアプリケーションを構築することができる、超軽量Webフレームワークです。

http://riotjs.com/ja/

カスタム・タグ

Viewと対になるScriptを、一つのタグに定義したものです。

HTML
└── Custom Tag
    ├── Custom Tag
    │   ├── HTML
    │   └── Script
    ├── HTML
    └── Script

コンパイラ

インブラウザ・コンパイルとプリコンパイルから選べます。 このハンズオンでは環境構築を簡素化するために、表示時にコンパイルされるインブラウザ・コンパイルを採用しています。

http://riotjs.com/ja/api/compiler/

私は普段、Webpackでプリコンパイル(&トランスパイル)させて、BundleされたJSを読み込むようにしています。

その際に利用する webpack.config.js 例です。

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: {
    index: path.join(__dirname, 'src/app.js')
  },
  output: {
    path: path.join(__dirname, 'public/scripts'),
    filename: 'app.js',
    library: 'Router'
  },
  plugins: [
    new webpack.ProvidePlugin({
      riot: 'riot'
    })
  ],
  module: {
    loaders: [
      { 
        test: /\.tag$/, 
        exclude: /node_modules/, 
        loader: 'riotjs-loader'
      },
      { 
        test: /\.json$/, 
        exclude: /node_module]s/, 
        loader: 'json-loader'
      },
      { 
        test: /\.js$/,
        exclude: /node_modules/, 
        loader: 'babel-loader' 
      }
    ]
  }
};

ちなみに、 package.json はこんな感じ。

{
  "name": "riot_twitter",
  "version": "1.0.0",
  "description": "",
  "dependencies": {},
  "devDependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.13.2",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.13.2",
    "json-loader": "^0.5.4",
    "riot": "^2.5.0",
    "riot-router": "^0.8.0",
    "riotjs-loader": "^3.0.0",
    "webpack": "^1.13.1",
    "webpack-dev-server": "^1.14.1"
  },
  "scripts": {
    "watch": "webpack --progress --color --watch"
  },
  "author": "omiend"
}

ルーティング

ルーティングにはriot.routeを利用します。

下記アクションでURLが変更されると、与えられたcallback関数を実行します。

  • 1.新しいURLが、ブラウザのロケーションバーに入力されたとき
  • 2.ブラウザの戻る/進むボタンが押されたとき
  • 3.route(to)が呼び出されたとき
  • 4.アンカータグがクリックされたとき

当TODOアプリにおいては、URLの変更を検知→URLの状態を受け取り、callback関数にてカスタム・タグをマウントさせています。

// 例えば、‘todo/1000/edit’にアクセスすると
// collection=‘todo’; id=‘1000’; action=’edit’がバインドされる
riot.route(function(collection, id, action){
  riot.mount('route', collection || 'home', {id: id})
})

参考までに、私は普段riot-routerを利用しています。

riot-router

こちらも気になっています。

riot-routehandler

ハンズオン

注意点

独学なので、Riot.jsのお作法に則っていない可能性があります(お作法がアレば、の話ですが)

Global変数をそのまま触っており(良くない)、JavaScriptについては割りと乱暴にお手軽に実装しています。

※observableを利用して、fluxを取り入れるべきだなぁとは感じています。

また、ローカル環境においては、カスタムタグを外部ファイルとして読み込むため

<script type="riot/tag" src="tags/home.tag"></script>

Google Chromeで起動すると下記のエラーが発生し、正常に動作しない可能性があります。

その際は、Google Chrome起動時に--allow-file-access-from-filesを引数を指定して起動するか、Firefoxなどの別のブラウザでお試し下さい。

riot+compiler.min.js:2 XMLHttpRequest cannot load file://hoge-hoge/riotjs_todo/tags/home.tag. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.

Python(MacOSならば標準搭載)を利用し、SimpleServerを利用する手もあります。

知らなかったPythonのSimpleServer

ローカル環境で動かしましょう

git clone git@github.com:omiend/riotjs_todo.git でもどうぞ
  • index.htmlをブラウザで開く

構成

.
├── css
│   ├── main.css      // ページの整形用に
│   ├── normalize.css // https://necolas.github.io/normalize.css/
│   └── skeleton.css  // わたくしomiendが好きな、軽量CSSフレームワークです( http://getskeleton.com/)
├── images
│   └── riotjs.png    // riotをイメージした画像
├── index.html         // ブラウザが一番初めに読み込む単純なHTMLファイルです
├── scripts
│   └── app.js        // ルーティングと、予め登録されたデータを格納しています
└── tags               // カスタム・タグを配置しているディレクトリです
      ├── add.tag      // TODOデータの追加を行うカスタム・タグです
      ├── commands.tag // TODOデータに対して何らかの処理を行うコマンドを集めたカスタム・タグです
      ├── edit.tag     // TODOデータを更新するためのフォームが定義されたカスタム・タグです
      ├── home.tag     // ホーム画面を表示するための簡単なHTMLが定義されたカスタム・タグです
      ├── navi.tag     // ナビバーの単純なHTMLが定義されたカスタム・タグです
      └── todo.tag     // TODOデータを一覧したりなど、TODOアプリの基盤画面を定義したカスタム・タグです

index.html

ブラウザで一番初めに読み込むファイルです。

内容は単純なHTMLですが、下記の要素が定義されています。

<!-- カスタムタグがマウントされるセレクター 名称はrouteでなくても良いです -->
<route></route>
<!-- Riot.js本体と、コンパイラをCDNで読み込み -->
<script src="https://cdn.jsdelivr.net/riot/2.6/riot+compiler.min.js"></script>
<!-- ルーティングなどの読み込み -->
<script src="scripts/app.js" defer></script>

tag/navi.tag

こちらは本当に単純なHTMLです。

コメントアウトを解除し、画面にナビバーが表示されることを確認してください。 正しく表示されていれば、naviタグが正しくマウントされているということです。

tag/home.tag

ルーティング設定によって、「/」にアクセスされた時ににマウントされるタグです。

同タグ内のScriptにて‘Riot.js’という値を返す関数「echo()」が定義されています。

I Love {this.echo()} !
」にて当該関数を実行し、 ‘Riot.js’を受け取ってレンダリングしています。

単純な例ですが、カスタム・タグの基本がわかると思います。

tag/todo.tag

TODOアプリケーションの基盤的なカスタム・タグです。

まず、riotが提供するeachによってTODOデータをループし、表示しています。

<div class="row" each={todo in store.todos}>

一行ごとにcommandsタグをマウントさせています。

commandsタグはtodoという名前を引数として、ループ中のtodoを受け取っています。

<commands todo={todo}></commands>

tag/commands.tag

todoタグから受け取ったTODOデータは、optsというriotが提供する特別な変数に格納されます。

optsは、Reactで言う所のpropsのイメージです。

<div if={opts.todo.done}><!-- doneがtrueだったらレンダリング -->

commandsタグは、TODOデータに対してアクションを行うボタンを提供するために実装したカスタム・タグです。

editTagをにマウントさせるために呼び出される関数。 フラグを更新する関数。 TODOデータを削除する関数を定義しています。

一つのカスタム・タグが、各行で各TODOデータのみを利用する動きとなっており、コンポーネントの再利用を意識した作りとしています。

tag/add.tag

addタグがマウントされるはtodoタグ内に定義されているので、addタグは子タグと呼べます。

子タグは親タグ(todoタグ)がマウントされた後に初期化されます。

TODO内容を入力し、ADDボタンがクリックされると、addタグに定義されたadd関数が実行され、storeに入力内容を保存します。

実はその後の「 store.trigger('refresh') 」が大切な処理です。

sroreはapp.jsにてobservableのオブジェクトとしており、add実行時にtriggerを実行することによって refresh イベントを発火させています。

riot.observable(store)

storeに対する refresh イベントが発火されると、todoタグに定義された下記のcallback関数が実行され、todoタグが自身を更新し、TODO一覧に追加したTODOデータが表示されるという仕組みになっています。

var self = this // callbackの中でtodoタグを参照するため
store.on('refresh', function(){
  self.update() // todoタグを更新
})

オブザーバブル(Observable)について http://riotjs.com/ja/api/observable/

tag/edit.tag

これまでの説明以上の目新しいことはしていません。

コメントアウトを解除して、更新画面が表示されることを確認してください。

commandsタグからリクエストパラメータでeditタグを呼び出し・・・

edit() {
  riot.route(`edit/${opts.todo.id}`)
}
riot.route(function(collection, id, action){
  // collection = edit
  // id = commandsタグの${opts.todo.id}で取得されたTODOデータのID
  riot.mount('route', collection || 'home', {id: id})
})

TODOデータのIDを opts を利用して受け取っています。

opts.form = store.todos.filter(function(s){return s.id == opts.id})[0]

参考にさせていただいたモノ

基礎

Router周り