2007年12月02日
LiveCoding#5 でコーディングしてきた
LiveCoding #5 でコーディングしてきました。
「はてブビューワーをFlexで作る」というのをやってみました。
成果物

完成品→http://tech.nitoyon.com/misc/live_coding5/test.swf
- 私のはてなブックマーク一覧が表示されます
- 上のリンクは件数を減らしていますが、本番では3,000件以上を表示していました
- ヘッダ部分でソートできます
- 選択した状態で [open] ボタンを押すと、別ページで開きます
- 検索のところに文字列を入れるとタイトルからリアルタイムで絞込みできます
やったこと
- http://b.hatena.ne.jp/はてなID/config?mode=export から RSS1.0 形式でブックマーク一覧をダウンロードする
- 冒頭の「 xmlns="http://purl.org/rss/1.0/" 」を削除する。これは Flex の DataGrid で名前空間つきの XML を扱えないから(なんとかしてほしい)。
- rascut を起動して、Test.mxml の簡単なのを書いてみる
- ランゲージリファレンスの DataGrid のサンプルをコピペ
- 不要な部分を削って、URLLoader でロードした XML を DataGrid に突っ込む
- 表示できた!(おー)
- ボタンクリックされたときにページを表示するようにする
- TextInput を作って、filterFunction でフィルタリング機能を作る
- タグの一覧をパースして、タグの個数を Object に突っ込むところを作る
- タグクラウドを表示したかったけど時間切れ
感想
PR したかったポイントは表現できたかな…。
- エディタとコマンドラインで Flash 開発できる(開発環境の Flex SDK は無料)
- DataGrid に XML を突っ込んだらそのまま表示できる(!)
- 3,000件(1.92MB)もある XML を難なくパースできる
- E4X 気持ちいいよね
- DataGrid は高機能
実は、5. のところまでは事前に研究していたのですが、そのときに E4X の名前空間で1時間ぐらいはまりました。DataGrid のソースを読んだのですが、DataGrid は名前空間つきの XML を表示できないようで、結局は上の 2. のひどい方法で対処しました。
LiveCoding は事前コーディング禁止だったので、半分は反則技ですね。とはいえ、研究してないと20分間悩んで終わっていたので、必要な技術の下調べは必要かもしれません。
あと、トップバッターで感覚が分からずひたすらコーディングしたのですが、他の人は喋りながらやっていたので、ある程度は解説しながらやったほうがよかったかな。
ソースコード
ソースコードは こちら に置いておきました。
いちおうここにも張っておきます(72行)
<?xml version="1.0"?>
<!-- DataGrid control example. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init()">
<mx:Script>
<![CDATA[
private function init():void
{
var loader:URLLoader = new URLLoader();
loader.addEventListener("complete", complete);
loader.load(new URLRequest("xml/dump.xml"));
}
private function complete(event:*):void
{
var loader:URLLoader = URLLoader(event.target);
var xml:XML = XML(loader.data);
dg.dataProvider = xml..item;
parseTag(xml);
}
private function parseTag(xml:XML):void
{
var ns:Namespace = new Namespace("http://purl.org/dc/elements/1.1/");
var tags:Object = {};
for each(var tag:XML in xml..ns::subject)
{
tags[tag.toString()] = tags[tag.toString()] ? tags[tag.toString()]+ 1 : 1;
}
trace(tags);
var a:Array = [];
for(var id:String in tags)
{
trace(id + " " + tags[id]);
}
}
private function clickHandler():void
{
var url:String = dg.selectedItem.link.toString();
navigateToURL(new URLRequest(url));
}
private function changeHandler():void
{
dg.dataProvider.filterFunction = function(item:Object):Boolean
{
return item.title.indexOf(q.text) != -1;
}
dg.dataProvider.refresh();
trace("change");
}
]]>
</mx:Script>
<mx:HBox>
<mx:Text text="検索"/>
<mx:TextInput id="q" change="changeHandler()"/>
</mx:HBox>
<mx:DataGrid id="dg" width="100%" height="100%" rowCount="5">
<mx:columns>
<mx:DataGridColumn dataField="title" headerText="title"/>
<mx:DataGridColumn dataField="description"/>
</mx:columns>
</mx:DataGrid>
<mx:Button label="open" click="clickHandler()"/>
</mx:Application>