LoginSignup
17
16

More than 5 years have passed since last update.

Riot.jsでobservableを使って簡易的な通知メッセージを表示する

Last updated at Posted at 2016-11-29

たとえばログインが完了したときとか、データの保存に成功したときとか、
ユーザーに対して処理の結果を 簡易的にフィードバックしたいことがあるわけです。

Railsだとflashという仕組みで簡単にできますね。

flash - Railsドキュメント

これをRiot.jsでもやりたい!ということでやってみました。

デザインにはおしゃれで有名なSemanticUIを使っていますが、bootstrapとかでも同じような書き方できるはず。SemanticUIおすすめ。

完成イメージ

flash.gif

環境

  • riot.js v3.0.0
  • SemanticUI v2.2.4

きましたv3!

メッセージを別タグにして読み込む

ログイン完了したあととかって、だいたい画面遷移するじゃないですか。
なので通知メッセージはタグ横断で表示したい。

ということでまずはメッセージ部分をflash.tagとして切り出し、
index.htmlでもろもろ読み込みの設定をします。
(ページごとの内容を<content>に出力するSPA的な想定です)

index.html
...
<body>
  <header></header>
  <div>
    <flash></flash><!-- ここにメッセージ表示するよ -->
    <content></content>
  </div>
  <footer></footer>

 ...

  <script>
    ...
    var obs = riot.observable();
  </script>
</body>

observableつかうよ

var obs = riot.observable();

タグ間で動作を連携させたいので、observableを使います。
というか今回はじめてつかった。便利!

ここではまだobservableを用意しただけ。
この後こいつのイベントを発火させ、それを受け取ることで、タグ間で動作を連携させます。

こちらの記事が大変わかりやすかったです。

【Riot.js】タグ間で動作を連動させる - Qiita

flash.tagを実装する

お次はflash.tagの中身を実装します。これが今回のメイン。

html部分はSemanticUIのmessageをほぼそのまま使ってるだけなので、非常にシンプル。cssもお好みで調整してください。

flashオブジェクトを受け取ったらメッセージが表示されるようになってて、flash.typeflash.textでメッセージの色と本文を設定できるようにしています。
(typeにはsuccessとかerrorとかが入るイメージ)

flash.tag
<flash>
  <div id="flasher" if={flash}>
    <div class="ui attached message {flash.type}">
      <i class="close icon" onclick={ close }></i>
      <div class="header">{flash.text}</div>
    </div>
  </div>


  <style>
    #flasher {
      width: 100%;
      position: fixed;
      z-index: 100;
      opacity: 0.9;
    }
  </style>


  <script>
    var that = this

    close(ms=0) {
      setTimeout(function(){
        $('#flasher').transition('fade')
        that.flash = null
        that.update()
      }, ms)
    }

    obs.on("flashChanged", function(obj) {
      that.flash = obj
      that.update()
      that.close(3000)
    })
  </script>
</flash>

一番下で、さっきのobservableがflashChangedというトリガーを受け取ったときのイベントを定義しています。

といってもやってることは非常にシンプルで、flashオブジェクトを受け取って画面を更新してるだけです。

これだけでもいいのですが、今回は数秒たつと自動で消えるようにしたかったので、close()メソッドをを定義して最後に呼び出しています。

Semanticで用意してくれてるtransition('fade')でふわっと消えるのがいい感じ。

メッセージを表示する

最後にイベント発火側の記述。
これも非常にシンプルです。

auth.tag
if(success) {
  obs.trigger("flashChanged", {type:'success',text:'ログインしました'})
}else {
  obs.trigger("flashChanged", {type:'error',text:'ログインに失敗しました'})
}

おまけ

同じようにして、ページ全体にローディング画面を表示するタグも作ってみました。

dimmer.tag
<dimmer>
  <div class="ui page dimmer {state}">
    <div class="ui indeterminate huge text loader">Loading</div>
  </div>

  <script>
    var that = this

    obs.on("dimmerChanged", function(state) {
      that.state = state
      that.update()
    })
  </script>
</dimmer>
auth.tag
obs.trigger("dimmerChanged", 'active') 

signup().then(
  function() {
    obs.trigger("dimmerChanged", '')
  })
)

こんな感じになりました。

capture.gif

まとめ

という感じで非常にお手軽にメッセージ通知機能ができました。
observable便利!

17
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
16