プッシュ通知は従来のマーケティング手法で言えばメールマーケティングに相当します。つまり一度配信してしまうと、後から取り消すのが難しい拡散方法ということです。そのため企業によっては一旦承認フローを経てからプッシュ通知を送りたいという要望も聞かれます。
そこで独自のプッシュ通知管理画面を作成して、承認フローを経るようにしてみたいと思います。作成していく過程をステップを踏んで説明していきますので、自社のフローに合わせてカスタマイズしてみてください。
今回はデータメンテナンス画面の処理について紹介します。
実際の処理について
このWebアプリケーションはVue.jsで構築されています。機能はコンポーネント化されています。今回は承認者のデータメンテナンス機能を作りますので、モーダル表示を行います。
モーダル表示について
モーダル表示を行う際には、Contents Management System - ニフティクラウドmobile backendのモーダル表示をベースにします。このHTMLをベースにして、config_manager.vueというファイルのtemplateタグを作成します。
このHTMLはbodyタグの直下に生成されるのを前提としています。そこで、config_form.vueの承認者の管理ボタンを押した時に、Appの処理を呼び出すようにします。
module.exports = { : methods: { : showManagerModal: function(e) { this.$emit('showModal', 'configManager'); } } }
もちろんAppやmain_content.vueではイベントを購読しておきます。
<router-view :ncmb="ncmb" v-on:updateKeys="updateKeys" v-on:showModal="showModal"></router-view>
今後、モーダル表示は複数パターンが考えられますので、モーダルの種類(今回はconfigManager)を指定できるようにしておきます。
export default { name: 'app', data: function() { return { ncmb: ncmb, error: null, success: null, modal: null // 追加 }; }, : methods: { : showModal: function(modal) { this.modal = modal; }, closeModal: function() { this.modal = null; }, }, : }
このように this.modal に文字列を入れるようにします。閉じる場合は this.modal = null にするだけです。
Appのテンプレート側では次のように記述します。modalがconfigManagerの時だけ表示します。
<template> <div> <config-manager id="config-manager" :ncmb="ncmb" v-on:errorMessage="errorMessage" v-on:successMessage="successMessage" v-on:closeModal="closeModal" v-if="modal == 'configManager'" /> : </div> </template>
これでボタンを押した際にモーダルが表示されます。
モーダルを閉じる
次にモーダルを閉じる機能を実装します。これはAppにあるcloseModalを this.$emit で呼び出すだけです。なお、クリックだけでなくESCキーでも閉じられるようにしています。
module.exports = { : methods: { cancel: function(e) { if (typeof e == 'undefined' || e.type == 'click' || (e.type == 'keyup' && e.keyCode == 27)) { }else{ return true; } this.$emit('closeModal'); } } }
データを読み出す
まず最初にデータストアからデータを読み込む部分を作ります。最初はデータはありませんが、その方がデータ登録後の処理が分かりやすくなります。これはDOMを生成した後の created イベントに対して作成します。
一覧の更新は他のメソッドからも使いますので、別メソッド化しておきます。order(並び順)カラムを使って並び順を指定します。データはそのまま this.managers の中に保存します。
module.exports = { props: ['ncmb'], data: function() { let data = { managers: [] }; return data; }, created: function() { window.addEventListener('keyup', this.cancel); this.updateList(); }, methods: { : updateList: function() { let me = this; let Manager = this.ncmb.DataStore('Manager'); Manager .order('order') .fetchAll() .then(results => { me.managers = results; }) .catch(err => { me.$emit('errorMessage', "データの取得に失敗しました") }) } } }
承認者を追加する
次に承認者を追加するアクションです。これは this.managers に対してデータストアのインスタンスを追加するだけです。
addManager: function() { let Manager = this.ncmb.DataStore('Manager'); let manager = new Manager; this.managers.push(manager); }
承認者を保存する
承認者を保存するアクションは次のようになります。this.managersを保存する処理は非同期処理になりますので、Promise.allでまとめて処理するようにします。manage.objectIdの有無でupdateまたはsaveメソッドを実行します。保存成功時に実行するme.cancel()はモーダルを閉じるアクションです。
save: function(e) { let me = this; let promises = []; for (let i = 0; i < this.managers.length; i++) { let manager = this.managers[i]; manager.set('order', i); promises.push(manager.objectId ? manager.update() : manager.save()); } Promise.all(promises) .then(results => { me.$emit('successMessage', "承認者を登録しました"); me.cancel() }, err => { me.$emit('errorMessage', "データの保存に失敗しました"); }) },
チェックボックスをすべて付ける
モーダル上部にあるチェックボックスを有効にすると一覧のデータすべてのチェックボックスが有効になります。これは this.managers にある各データの checked を trueにすればOKです。
checkAll: function(e) { let managers = []; for (let i = 0; i < this.managers.length; i++) { let manager = this.managers[i]; manager.checked = e.target.checked; managers.push(manager); } this.managers = managers; },
HTML側は次のようになります。
<input type="checkbox" v-model="manager.checked">
承認者を削除する
承認者を削除する場合は this.managers のデータの中で checked が有効になっているデータを対象にします。こちらもすべて非同期処理になりますので、Promise.all を使って一括処理を行います。今回は削除処理を行った場合はリストを取得し直しています。
deleteManager: function() { let promises = []; let me = this; for (let i = 0; i < this.managers.length; i++) { let manager = this.managers[i]; if (manager.checked) { promises.push(manager.delete()); } } Promise.all(promises) .then(results => { me.updateList(); }, err => { me.$emit('errorMessage', "データの削除に失敗しました"); }) },
並び替える
最後にデータの並び替えです。今回は一つ上または下のデータと入れ替える形になっています。そこでHTML側から -1 (上げる)または +1 (下げる)を送るようにします。
<a type="button" class="btn" style="text-decoration:none;" @click="moveManager(manager, -1)">↑</a> <a type="button" class="btn" style="text-decoration:none;margin-left:1px;" @click="moveManager(manager, 1)">↓</a>
そして対象になる承認者データを探し、それと一つ前または後ろのデータを入れ替えます。
moveManager: function(o_manager, order) { for (let i = 0; i < this.managers.length; i++) { let manager = this.managers[i]; if (manager !== o_manager) continue; if (!this.managers[i + order]) continue; Vue.set(this.managers, i, this.managers[i + order]); Vue.set(this.managers, (i + order), o_manager); return; } }
一番上や下のデータの場合、入れ替え対象になるデータがない場合もありますので、チェックするようにします。後は配列のインデックスを指定してデータを差し替えればOKです。
ここまでの処理でマスタデータのメンテナンスができるようになりました。同じような操作でプッシュ通知に必要なデータメンテナンスを実現しましょう。
プッシュ管理のコードはNCMBMania/pushManager at v0.2にアップロードされています。実装時の参考にしてください。