WixStudioでVeloを使う Step 18 「コレクションを使う - 参照」
はじめに
何を作りたいかはあまり気にしていなくて。ただ、Veloで色々試したい。特にコレクションに触れたら試したいことばかりになってしまった。そして、触れずにはいられない「参照」。コレクションのフィールドタイプとして「参照」が登場する。コレクションの参照を使った検証を行ってみる。
コレクションの参照
コレクションはとても便利。たくさんのアイテム(情報)を効率良く管理できる。基本的にコレクションは予め決めたテーマに絞った情報を管理する。例えばHolidaysコレクションは「祝日」というテーマに絞って情報を管理している。だから、登録されている情報は、そのテーマの幅を超えることはない。要は、Holidaysコレクションのアイテムは「『祝日』の情報以上の情報を持たない」ってこと。当たり前のことだけでこれが重要。で、WixStudioでは必要に応じてコレクションを増やすことが出来る。例えば「場所」の情報を集めた Placesコレクション とか、「人」の情報を集めた Personsコレクション という感じ。これらのコレクションの各情報もテーマの幅を超えた情報を持つことはもちろんない。ここで「参照」。もし、「祝日」「場所」「人」という3つのテーマの情報が相互に関連し合ったらって考える。そうすると今まで表現できなかったモノが表現できる可能性が出てくる。例えば「遊びの約束」とか「祝日の思い出」とか。「いつ(祝日)、だれ(人)と、どこ(場所)へ行く」といった具合。当たり前のようだけど、情報は単体で存在するよりも、情報同士が繋がりあうほうが可能性が広がってくる。この繋がりを実現するのが「参照」ということになる。
フィールドタイプの「参照」
目的
「参照」を使う。出来上がるモノとしては、祝日ページに掲示板のようなコメント投稿を追加する。
準備
前回の続きです。
- Holidaysコレクションが必要。
- 祝日のアイテムページが必要。
Commentsコレクションを作成する
コレクションを作成するが、先にVeloは有効にしておいたほうがいい。Veloを有効にしているかどうかで表示されるダイアログの内容が異なる。特にコレクションのIDやフィールドキーなどを確認するにはVeloを有効にしておく必要がある。
Commentsコレクションを作成
Commentsコレクションの目的は「コメントを管理する」こと。短文のメッセージ的な文字列情報を管理する。恐ろしくつまらないコレクションに思えてきた。
フィールドを作成
フィールドは2つ作成する。
MessageフィールドとHolidayフィールド。
Messageフィールドを作成する
Messageフィールドには祝日に対するコメントを格納する予定。
Messageフィールドを作成」
せっかくなので制約も設けておく。
Messageフィールドを必須にしておく
Messageフィールドの設定値はこんな感じ。
項目名 | 項目値 |
---|---|
フィールドタイプ | テキスト |
フィールド名 | Message |
フィールドキー | message |
制約 | 必須項目にする |
Holidayフィールドを作成する
こちらはフィールドタイプが「参照」。
Holidayフィールドを作成
Holidayフィールドにも制約を設けておく。フィールドの設定値はこんな感じ。
項目名 | 項目値 |
---|---|
フィールドタイプ | 参照 |
フィールド名 | Holiday |
フィールドキー | holiday |
参照先コレクション | Holidays |
制約 | 必須項目にする |
フィールドの作成が完了。
パーミッションの設定
コメントを登録出来る人を今回は制限しない。誰でも試せるようにしたい。
2つめのパーミッション「『すべてのユーザー』はコンテンツの追加が可能」としておく。
パーミッションを変更する
サイトを公開せずにプレビューだけで検証する場合はこの設定は不要。
コレクションに関する設定も終わり。
Commentsコレクションの作成が完了
Holidays(Code)画面を改造する
Holidays(Code)画面は、動的ページで祝日のアイテムページ。
Holidays(Code)
Holidays(Code)画面には祝日に対するコメントを残せるようにする。さらに、残されたコメントも一覧で見られるようにしたい。リピータとボタンと入力欄を設置する。
まずは、ボタンと入力欄。
ボタンと入力欄
レイアウトにこだわり無し。このボタンと入力欄は、コメントを登録する為のフォームとして機能させる予定。入力欄は「テキストボックス」を利用した。複数行入れられた方がなんとなく心地良い気がした。
後ほどVeloで必要になるボタンとテキストボックスの情報
項目名 | 項目値 | 用途 |
---|---|---|
ID | button3 | コメントの登録ボタン |
項目名 | 項目値 | 用途 |
---|---|---|
ID | textBox1 | コメントの入力 |
次にリピータを設置する。リピータにはテキスト要素を2つ設置する。
リピータ設置
リピータの情報
項目名 | 項目値 | 用途 |
---|---|---|
ID | repeater1 | コメントの一覧を表示 |
リピータに配置されたテキスト要素
リピータに配置されたテキスト要素の情報
項目名 | 項目値 | 用途 |
---|---|---|
ID | text6 | コメントが登録された日付を表示させる |
項目名 | 項目値 | 用途 |
---|---|---|
ID | text7 | コメントの本文を表示させる |
これでHolidays(Code)画面の改造が完了。
完成したHolidays(Code)画面
スクリプトを書く
今回はページコードに全て書く。
ページコード - Holidays (Code).###.js
意外とスクリプトのボリュームがあるが内容は大きく分けて2つ。
- Commentsコレクションの内容をリピータに反映する。
- アイテムの取得
- リピータの初期化
- Commentsコレクションに新しいコメントを登録する。
- 登録オブジェクトの生成
- 保存
それぞれを達成させる処理を書く。
import wixData from 'wix-data'
$w.onReady(function () {
const holiday = $w("#dynamicDataset").getCurrentItem()
const repeater = $w('#repeater1')
const initRepeater = () =>{
wixData.query('comments')
.eq('holiday',holiday._id)
.descending('_createdDate')
.find()
.then( results => {
repeater.data = results.items
})
}
initRepeater()
repeater.onItemReady( ($item,itemData,index) => {
$item('#text7').text = itemData.message
$item('#text6').text = itemData._createdDate.toLocaleString()
})
$w('#button3').onClick( event => {
const comment = {}
let input = $w('#textBox1').value
comment.title = input.split(/\r\n|\n|\.|。/)[0]
comment.message = input
comment.holiday = holiday
wixData.save('comments',comment)
.then( item => {
$w('#textBox1').value = null
initRepeater()
})
.catch( error => {})
})
})
Commentsコレクションの内容をリピータに反映する
まずは、ページがコードが読み込まれたらすぐに実施してる1行に注目。
const holiday = $w("#dynamicDataset").getCurrentItem()
const holiday = $w("#dynamicDataset").getCurrentItem()
は現在のページの対象となっているHolidaysコレクションの祝日オブジェクトを取得している。この理解にはDatasetとDynamicDatasetに触れる必要がある。
アイテムページで1955-01-01_元日を開いているとき
DatasetとDynamicDataset
データセットはページに配置された要素とコレクション(CMS)を接続する仕組み。ページに配置したリピータやフォームをコレクションを連携させるときには手動で配置して設定する。今まではリピータやフォームの操作をVeloで処理してきたのでデータセットについては今まで触れてきてない。
データセットは要素として配置できる
アイテムページ(動的ページ)を作成するとDynamicDatasetという特殊なDatasetが接続されるっぽい。そもそも動的ページは連携したコレクションの要素に応じてページの存在が変化する。Datasetの存在が不可欠なんだと思う。
DynamicDatasetは$w("#dynamicDataset")
とするとVeloから操作できる。さらに.getCurrentItem()
で現在のページ生成の対象となっているアイテムが取得出来るようになっている。これによって「1955-01-01_元日」のオブジェクトが取得出来ている。
リピータの初期化
リピータの初期化処理はいくつかのタイミングで行われる。
- このページを表示したタイミング
- コメントを登録したタイミング
だから関数化して使い回せるようにしておく。
const repeater = $w('#repeater1')
const initRepeater = () =>{
wixData.query('comments')
.eq('holiday',holiday._id)
.descending('_createdDate')
.find()
.then( results => {
repeater.data = results.items
})
}
initRepeater()
const repeater = $w('#repeater1')
でページ内のリピータを取得。リピータへの反映処理はconst initRepeater = () =>{...}
で処理を関数化。すぐにinitRepeater()
で呼びだしてる。
initRepeater()
では、表示すべきコメントの抽出を行う。具体的にはwixData.query(
comments).eq('holiday',holiday._id).descending('_createdDate')
。Commentsコレクションから、現在表示している祝日のコメントに絞り込み、登録の新しい順に並べ替えている。initRepeater()
はリピータにデータをセットするまでしかやらない。リピータはデータセットされたら.onItemReady()
が呼び出されるのでそちらも定義しておく。
repeater.onItemReady( ($item,itemData,index) => {
$item('#text7').text = itemData.message
$item('#text6').text = itemData._createdDate.toLocaleString()
})
Commentsコレクションに新しいコメントを登録する
Commentsコレクションへの登録をしているコードはこの辺。
$w('#button3').onClick( event => {
const comment = {}
let input = $w('#textBox1').value
comment.title = input.split(/\r\n|\n|\.|。/)[0]
comment.message = input
comment.holiday = holiday
wixData.save('comments',comment)
.then( item => {
$w('#textBox1').value = null
initRepeater()
})
.catch( error => {})
})
一番重要なところはwixData.save('comments',comment)
。コレクションにデータを登録するときに使う。
.save()
の結果はPromise<WixDataQueryReferencedResult>
で返されるので.then()
で処理する。正常に登録出来た際の処理内容は2つ。入力欄を空にする($w('#textBox1').value = null
)、リピータを再設定する(initRepeater()
)。
.save()
の引数は2つ。一つ目には登録先のコレクションIDを指定する。今回はCommentsコレクションが対象。二つ目の引数は登録したい情報をオブジェクト形式で渡す。
const comment = {}
で空のオブジェクトを作成している。このオブジェクトはCommentsコレクションの列と対応する属性を持たなければならない。Commentsコレクションは「Title」「Message」「Holiday」の3列。これらのキーを属性として持つオブジェクトを作成すれば良い。
const comment = {}
let input = $w('#textBox1').value
comment.title = input.split(/\r\n|\n|\.|。/)[0]
comment.message = input
comment.holiday = holiday
let input = $w('#textBox1').value
は入力内容を取得。input.split(/\r\n|\n|\.|。/)[0]
は入力内容の初めの1行目(もしくは最初の「。」や「.」が登場するまで)の内容を取得している。CommentsコレクションのTitle列にはこの値を設定することに急遽決めた。全く無計画。Message列には入力内容全文。Holiday列にはholiday
を指定した。
Holiday列はフィールドタイプが「参照」
Holiday列の内容を再確認。
項目名 | 項目値 |
---|---|
フィールドタイプ | 参照 |
フィールド名 | Holiday |
フィールドキー | holiday |
参照先コレクション | Holidays |
制約 | 必須項目にする |
Holiday列は参照タイプのフィールド。そして、参照先コレクションがHolidaysとなっている。参照タイプのHoliday列に格納するのはHolidaysコレクションのアイテムオブジェクト。か、ID列(_id
)の値。
HolidaysコレクションのID列
動作確認
祝日のアイテムページを一つ開く
コメントはまだ一つも無いのでリピータは表示されていない。実際に値を入力してみる。
コメントを入力してみる
入力内容は敢えて改行を含めた。Sendボタンを押す。
リピータが表示される
リピータが表示され、入力したコメントが確認出来るようになる。念のため他の祝日ページも開いてみる。
コメントは他の祝日には表示されない
登録したコメントは「1955年1月1日の元日」への参照をHoliday列に設定している。他の祝日とは関係を持たないので「1955年1月15日の成人の日」では表示されない。Commentsコレクションも確認する。
Commentsコレクション
Title列やHoliday列の値も正しく設定されていることが確認出来る。
まとめ
情報同士が関連し合うと、単体では表現できない情報の形が見えてくる。情報を扱うのは面白いと思う。どんな情報をどんな形で管理して連携させ合うかで、面白い仕組みを幾らでも作れると思う。今回試してみて、参照を使うことよりも、DynamicDatasetの存在が大きかった。これに気づけないと先に進めなかった。文献を見ていても、突然$w("#dynamicDataset")
と書かれているものが多い。その存在が何者なのか理解するのに苦労した。たしかにアイテムページを確認して見ると動的ページデータセットというものが確認出来た。これがDynamicDatasetなのかは未だに不明。いずれにしても$w("#dynamicDataset")
で情報が取得出来るので忘れないでおくようにする。
アイテムページに接続されている動的ページデータセット
Discussion