LoginSignup
35
36

More than 5 years have passed since last update.

Vue.js+firebaseでJS MVVMフレームワークに入門する(2/2)

Last updated at Posted at 2014-08-20

はじめに

(1/2)はこちら

前回firebaseの機能を20行のコード追加で動くようにしてみました。

まとめると

  1. 配列への要素追加時にcallback関数が呼ばれるので、 そのcallback関数内でVue.jsのModelへの追加処理を行う
  2. 元々の「Vue.jsのModel内の配列へ要素追加を行う」処理だった部分を「firebaseのModelへ要素追加を行う」処理に変更。

上記2点の処理追加or変更を行いました。
図にするとこういうイメージになります。
model_s.png

上図のVue.jsのModelとfirebaseのModelの間の追加処理の部分を実装したイメージとなります。
それ以外はそれぞれのライブラリが吸収してくれるわけですね。便利です。

今回は更に、要素に対する「変更」、「削除」も対応してみます。

配列に対する追加、変更、削除のコールバック関数の対応は以下となります。

firebaseのModelの変更をVue.jsのModelに反映する

firebaseのModelを取得

Model
var baseURL = 'https://<<アプリのURL>>.firebaseio.com/',
var Messages   = new Firebase(baseURL + 'messages');

firebaseが配列への追加を検出した際のcallbak

event_type:child_added

追加

Message.on('child_added', function (snapshot) {
    var message = snapshot.val();
    message.id = snapshot.name(); //識別子を取得しvue.jsのModelへ登録しておく。この値で変更時のオブジェクトを検出する
    app.messages.push(message); //vue.jsのmodelへの追加処理
});

firebaseが配列要素変更を検出した際のcallbak

event_type:child_changed

変更
Message.on('child_changed', function (snapshot) {
  var id = snapshot.name();
    app.messages.some(function(message) {
        if (message.id === id) {
            message.body = snapshot.val().body; //変更の反映
            return true;
        }
    });
});

firebaseが配列要素削除を検出した際のcallbak

event_type:child_removed

削除
Messages.on('child_removed', function (snapshot) {
    var id = snapshot.name();
      app.messages.some(function(message) {
          if (message.id === id) {
            app.messages.$remove(message); 
            return true;
          }
      });
  });

Vue.jsのModelの変更をfirebaseのModelに反映する

追加

追加
Messages.push(this.newMessage);

変更

変更
Messages.child(message.id).child('body').set(message.body);//事前にidを保存しておかないとここで変更ができない

削除

削除
Messages.child(message.id).remove();//事前にidを保存しておかないと削除できない

コード全体

chat_2.html
<html id="app">
  <head>
    <title v-text="title"></title>
    <script src="https://cdn.firebase.com/js/client/1.0.2/firebase.js" charset="utf-8"></script>
    <script src="http://vuejs.org/js/vue.min.js" charset="utf-8"></script>
  </head>
  <body>
    <div v-repeat="message:messages">
        {{$index}}
        <input v-model="message.body" value="{{message.body}}" v-on="keyup:changeMessage(message)">
        from:{{message.from}}
        <button v-on="click:deleteMessage(message)" >x</button>
        <br>
    </div>
    <form id="form" v-on="submit:addMessage">
        from:<br>
        <input v-model="newMessage.from">
        <br>
        message:<br>
        <input v-model="newMessage.body">
        <input type="submit" value="Add Message">
    </form>
  </body>
  <script charset="utf-8">

  //追加箇所
  var baseURL = 'https://<<自分のURL>>.firebaseio.com/',
  Messages   = new Firebase(baseURL + 'messages');

  //追加時
  Messages.on('child_added', function (snapshot) {
      var message = snapshot.val();
      message.id = snapshot.name(); //識別子を取得しvue.jsのModelへ登録しておく。この値で変更時のオブジェクトを検出する
      app.messages.push(message); //vue.jsのmodelへの追加処理
  });

  //変更時
  Messages.on('child_changed', function (snapshot) {
    var id = snapshot.name();
      app.messages.some(function(message) {
          if (message.id === id) {
              message.body = snapshot.val().body; //変更の反映
              return true;
          }
      });
  });

  //削除時
  Messages.on('child_removed', function (snapshot) {
    var id = snapshot.name();
      app.messages.some(function(message) {
          if (message.id === id) {
            app.messages.$remove(message); 
            return true;
          }
      });
  });

  var app = new Vue({
      el: '#app',
      data: {
          title:'Hello myChat',
          messages: [],
          newMessage: {
              from: '',
              body: ''
          },
      },
      methods: {
          addMessage: function(e) {
              e.preventDefault(); //submitをキャンセル

              Messages.push(this.newMessage);
              this.newMessage.body = ''

          },
          changeMessage: function(message) {
            console.log("changeMessage:" + message.body);
            Messages.child(message.id).child('body').set(message.body)
          },
          deleteMessage: function(message) {
            console.log("deleteMessage:" + message.body);
            Messages.child(message.id).remove();
          }

      }
  });

  </script>
</html>

課題

ここまでは、簡単に作れて感動しましたが、
DB周りが完全公開状態でやりたい放題なのを、なんとかする必要があります。
次回はその辺をまとめてみます。

おまけ:firebaseのダッシュボードから変更したり、変更を見たりできる。

dashboard.gif

35
36
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
35
36