(H) クラウドBigtable登録エンティティの参照
ここではgaedirectを使用して、クラウド上のBigtableに登録されているチャット書込みデータを参照し、ブラウザ画面上に表示していますが、画面表示ではDOMノード操作でタグの生成を行っています。
リスト5 多機能チャットプログラム-3 (channelHtl5.htm)
01 | //(H) 開始:クラウドBigtableを参照 |
03 | var pnode = document.getElementById("splist"); |
04 | for (var i =pnode.childNodes.length-1; i>=0; i--) { |
05 | pnode.removeChild(pnode.childNodes[i]); //(1) |
08 | var id = "uname,uemail,umsg,lat,lon,utime"; |
10 | query = qinit(kind, id); |
11 | query["SORT"] = "utime:DESCENDING"; //(2) |
12 | query["LIMIT"] = "10"; //(3) |
13 | $.get(gae(), query, function(res){ //(4) |
14 | var entity = res.split("<e>"); |
15 | for(var i = 0; i < entity.length ; i++){ |
16 | var prop = entity[i].split("<p>"); |
17 | splist(listno++, prop[1], prop[2], prop[4], prop[5], setutime2(prop[6]), prop[3]); //(5) |
21 | function splist(listno, uname, uemail, lat, lon, utime, umsg){ //(6) |
23 | if(listno < 0 ){ //(7) |
24 | tr1= document.getElementById("splist").insertRow(0); |
26 | tr1= document.getElementById("splist").insertRow(listno*2); |
28 | var td1_1 = tr1.insertCell(0); //(8) |
29 | td1_1.width = '10'; //(9) |
30 | td1_1.innerHTML = "<input type='checkbox' name='upcloud' id='"+listno+"'>"; |
31 | var td1_2 = tr1.insertCell(1); |
34 | var td1_3 = tr1.insertCell(2); |
36 | td1_3.id = 'uname'+listno; //(10) |
38 | var td1_4 = tr1.insertCell(3); |
40 | td1_4.id = 'uemail'+listno; //(11) |
42 | var td1_5 = tr1.insertCell(4); |
44 | td1_5.id = 'lat'+listno; //(12) |
46 | var td1_6 = tr1.insertCell(5); |
48 | td1_6.id = 'lon'+listno; //(13) |
50 | var td1_7 = tr1.insertCell(6); |
52 | td1_7.id = 'utime'+listno; //(14) |
53 | td1_2.appendChild(document.createTextNode(listno)); //(15) |
54 | td1_3.appendChild(document.createTextNode(uname)); |
55 | td1_4.appendChild(document.createTextNode(uemail)); |
56 | td1_5.appendChild(document.createTextNode("緯度:"+lat)); |
57 | td1_6.appendChild(document.createTextNode("経度:"+lon)); |
58 | td1_7.appendChild(document.createTextNode("時間:"+utime)); //(16) |
60 | if(listno < 0 ){ //(18) |
61 | tr2 = document.getElementById("splist").insertRow(1); |
63 | tr2 = document.getElementById("splist").insertRow(listno*2+1); |
65 | var td2_1 = tr2.insertCell(0); |
67 | var td2_2 = tr2.insertCell(1); |
69 | td2_2.colSpan = 6; //(19) |
70 | td2_2.id = 'umsg'+listno; |
71 | td2_2.appendChild(document.createTextNode(umsg)); |
74 | //(H) 終了:クラウドBigtableを参照 |
[Bigtable登録エンティティの参照処理]
gaedirectでの参照アクセス
リスト5のrev_remote関数は、Bigtableへの書き込みデータ参照を行っています。(1)のremoveChildで現在の一覧表示データをすべて消去した後、gaedirectでの条件参照を行っていますが、NoSQLのBigtableでも基本的な条件参照処理を行うことができます。
参照では(2)で書き込み時間での降順ソートを、(3)で先頭の10件まで検索することを指定して、(4)のgaedirectにより条件参照を実行しています。この条件指定から書き込みの新しい方から10件迄が画面表示されます。
参照データの表示
参照データを使用したブラウザ画面への表示は(5)から呼び出される(6)のsplist関数で行われていますが、この関数内の処理はDOMノード操作を使用して行われています。
・DOMノード操作でのテーブルタグ生成
(7)ではlistnoの値で処理を切り分けています。Listnoがマイナス値の場合は画面ロード時に表示されているリストの先頭に、新規に書き込まれたメッセージを追加する場合で、マイナス値でない場合は、リスト一覧の最後に追加します。
ここで使用されているinsertRowはTABLEまたはTBODYに新しい行(TR)を追加するメソッドで、TABLEにinsertRowを適用した場合には、自動的にTBODYが追加されてその下に、TR行を追加することになります。
ここでは、ID値”splist”のTBODYタグにTRタグ(tr1)を追加しています。
1 | <tbody id="splist" width="760"><tr></tr></tbody> |
(8)では生成したTRタグ(tr1)にinsertCellを適用しています。insertCellは行(TR)にセル(TDタグ)を追加/挿入します。引数で指定される値は、挿入するセルの場所を指定しており、先頭が0から始まるインデックス番号になっています。引数を指定しない場合は"-1"で、新しいTDタグをcellsコレクション(それまでに追加されているTDタグ)の直前に追加します。
1 | <tbody id="splist" width="760"><tr><td></td></tr></tbody> |
(9)では追加したTDタグのセル幅を指定していますが、これはTABLEタグを生成するときの省略形で、基本的なDOMノード操作書式では次のように指定します。 td1_1.setAttribute("width", "10");
1 | <tbody id="splist" width="760"><tr><td width=”10”></td></tr></tbody> |
次の行でTDタグにinnerHTMLを適用していますが、innerHTMLは、指定されたタグ(TD)の子ノードになる全てのタグをすべて消去し、そのあと、右辺で指定されているタグ記述を子ノード接続します。ここでは INPUTタグが指定されているので、TDタグの子ノードとしてINPUTタグが追加されて、タグ記述としては次のようになります。
1 | <tbody id="splist" width="760"> |
2 | <tr><td width=”100”><input type='checkbox' name='upcloud' id='"+listno+"' /></td></tr> |
その後同様の処理記述を繰り返してTDタグを追加していきますが、(10)~(14)では、それぞれのTDタグにID属性とその値を指定しています。これはTABLEの表形式になっている、各TDタグを一意に特定できるようにするための処理で、例えば(10)の’uname’ はBigtable登録時のプロパティ名で表示列を一意に特定し、その後に追加されているlistnoで表示行を一意に特定しています。したがって、この2つを連結して、例えば 'uname'+listno とすれば、テーブル表示上でのセル位置を一意に特定できることになります。
テキストノードのタグ生成と接続
(15)~(16)では同じ書式の処理を繰り返していますが、ここではテキストノードを生成して、それをTDタグの下に追加しています。
操作では、 document.createTextNodeで引数に指定される内容で、テキストを生成し、それをappendChildでtd_2~td_7の各TDタグの子ノードとして追加しています。
登録メッセージの表示では1つのメッセージを2行で表示しており、(17)以下は2行目のタグ生成を行っています。(18)のif文は1行目と同様に、一覧の最初にTR行を追加するか、最後に追加するかの判定を行っており、1行目と同様の操作でタグ生成を行っています。2行目ではメッセージ内容の表示を行うため生成されるTDタグは2つだけで、そのため(19)ではCOLSPANで6を指定しています。
メモ:DOMノードツリーの作成と表示パフォーマンス
ここでは関数の中でタグ生成を行う事と見やすさという点もあって、タグを順次上から作成し、都度HTMLタグ記述のTBODYタグに接続するようになっています。しかし、表示パフォーマンスという点では、DOMツリー構成でDOCUMENTノードに繋がっているTBODYへの子ノード接続は最後に1回だけ行うようにした方が表示(レンダリング)のスピードは向上します。つまり、TBODYタグに接続するタグ構成を、接続しないまますべて作成しておき、最後に一回のappendChildで、作成したノード構成がすべてTBODYに子ノード接続されるようにすれば、表示スピードは向上します。