SlideShare una empresa de Scribd logo
1 de 100
Descargar para leer sin conexión
goog.ui.Componentのはぐれ方
  アリエル・ネットワーク開発部 高村
私
 高村壮一(@stakamur)
HTMLとCSSをひたすら書く
          ↓
        jQuery
          ↓
     vimとのであい
         ↓
   Closure Library
         ↓
こないだから Sencha Touch ..

開発部UIチームで働いています
github projects
piglovesyou / flickGal (jQuery)
piglovesyou / closure-scroller
piglovesyou / closure-thousandrows
yan-yan-yahuoku.com




・・・あとは、Closure Library を使って作ったウェブサービスを、最近公開しました。
ヤンヤンヤフオクといって、ヤフオクの大量の商品を、軽い動作で一覧できるのが特徴です。

このサービスを作る前に、ひとつ試したいことがありました。それが、
goog.ui.Component インスタンスを
             徹底的にツリー化しよう




・・ということです。
/** @constructor */
    app.ui.Component = function () {
       goog.base(this);

          var child = new app.ui.Another();
          this.addChild(child);
    };
    ...




ツリー構造とは、画面の各構成部分を全てui.Componentで管理させた上での、

それらの親子関係のことです。
app

        child                 child




child                 child
ツリー化することは、
             とくべつなアイデアではない。




むしろ、Closure LibraryにはaddChildなどのメソッドがあることから、奨励していると思う
http://tiny-word.appspot.com


伊藤 千光さん が書かれた、Closure 本のデモでも、

コンポーネントのツリー化を基礎に設計されています。
ツリー化は、基本。
(例外はやまほどあるだろう)
しかし、ツリー構造を作りにくいときも・・




ルールがあるところに例外はつきもの。

ルールから外れたときこそ、フレームワークの真価が問われる。

そこで、今日お話したいのは、・・・
前半:なぜ、goog.ui.Componentを   後半
   ツリー化すべきなのか?
tを   後半:goog.ui.Componentのはぐれかた
?        ツリー化する上での例外ケース3種類
前半:なぜ、goog.ui.Componentを
   ツリー化すべきなのか?
はじめに:goog.ui.Componentの簡単な説明




ui.Component は、UIモジュールです。
http://closure-library.googlecode.com/svn/docs/class_goog_ui_Component.html




クラス関係です。
http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/index.html
インターフェース
var component = new app.ui.Component();
     component.render();




インターフェースです。

どこかのコードで、こう書くと、componentは自分でelementを作り出し、同時にdocument.body 配下に
elementをappendします。
var component = new app.ui.Component();

    var el = goog.dom.getElement(‘component-wrapper’);
    component.decorate(el);




似た機能で、decorate があります。elementのcreateとappendのコストをはぶけ、パフォーマンスの向上が
見込めます。

しかし、アプリではelementの動的な生成が基本なので、decorateに関しては今日は触れません。
実装
app.ui.Component.prototype.createDom = function () {
         var dh = this.getDomHelper();
         this.setElementInternal(dh.createDom('div', null));
    };


    app.ui.Component.prototype.enterDocument = function () {
         goog.base(this, ‘enterDocument’);
         this.getHandler().listen(this.getElement(),
              ‘click’, function() {(‘handle on click’);});
    };



createDom では、自分が管理するelementを作り、それをメンバーにセットします。

enterDocumentは、elementが必ずあることが前提のコードを書く場所です。
なぜ、element生成とenterDocumentが
       分かれているのか
コンストラクタ

                             ↓
                         createDom
                             ↓
                       enterDocument
                             ↓
                        exitDocument
                             ↓
                          dispose




elementがないと、エラーになってしまう処理を、enterDocumentに集めることで、
ui.Componentの安全で効率的なライフサイクルを提供できるからです。
コンストラクタ

                             ↓
                         createDom
                             ↓
 • DOM Exception を防ぐ   enterDocument
 • enter したときだけ
                             ↓
   listener を持たせられる
   (exit したら外せる)        exitDocument
                             ↓
                           dispose




このステップを踏むことで、ブラウザJavascriptにありがちなDOM Exception を防ぐことができます。

あとは、exitDocumentで、よけいなリスナ関数を除去することで、パフォーマンス、メモリ効率も上げられ
ます。
goog.ui.Componentの
簡単な説明 おわり
前半:なぜ、goog.ui.Componentを
              ツリー化すべきなのか?




あらためまして。
3つの理由
逆に、もし大量のインスタンスを
ツリーで管理しなければ、どうなる?
http://closure-library.googlecode.com/svn/docs/class_goog_ui_Component.html




まず、スーパークラスであるgoog.Disposable の恩恵を受けられなくなります。
var component = new app.ui.Component();


    (‘...’);


    component.dispose();




goog.Disposeは、もっともベーシックな破棄機能を提供します。
var component = new app.ui.Component();


      (‘...’);


      component.dispose(); // 内部オブジェクトの参照の破棄

                         // element と参照の破棄

                         // リスナの破棄

                         // 子インスタンスのdispose




disposeの実装のおかげで、インスタンスは自分に責任のがる他のオブジェクトを確実に破棄することができ
ます。

更に、ツリー構造にしておけば、子インスタンスのdisposeも走らせてくれます。
理由その1:(ツリーにしないと)
     関連するインスタンスのdisposeが、
           大変になる。




もし
http://closure-library.googlecode.com/svn/docs/class_goog_ui_Component.html




次に、EventTarget の恩恵も得られなくなります。
var component = new goog.ui.Component();


    goog.events.listen(component, 'shout', function(e) {
          console.log('shut up!!!');
    });


    component.dispatchEvent('shout');




EventTargetは、自身をelementのようなイベントターゲットのターゲットにします。

これにより、Observer パターンを提供します。
大量のインスタンスが、
        お互いに通信し合う必要があったら?




では、もし大量のインスタンス同士が・・・?

大変です。
参照をみつけだし、ひとつひとつ
   listenするのは大変・・・




           listen      listen         listen




まず、イベントをlistenするために参照を得なければなりません。また、インスタンスの数だけリスナが必要
になるでしょう。

シングルトンのEventTarget を利用したりもするかも知れない。
それはとてもいいことだけど、いつもそれをするとイベントが複雑になりすぎる。
var parent = new goog.ui.Component();
      goog.events.listen(parent, 'shout', function(e) { ('shut up!') });


      for (var i=0; i<10; i++) {
          var child = new goog.ui.Component();
          child.setParentEventTarget(parent);
      }


      child.dispatchEvent('shout');




それを解決するのが、EventTarget のメソッドである、setParentEventTargetです。

これにより、インスタンス同士の関係を築くことができます。
bubbling
    parent




       capture




                           child.dispatchEvent()


DOMと同じ。子で発生したイベントは、ルートインスタンスまで通知されます。
listen は1回。
                                        イベントが勝手に飛んでくる。
                               listen




     dispatch
                    dispatch                  dispatch




listenは1回でok。子がdispatchしたイベントは、親のもとに自動的に集められます。

子は、親に処理をデリゲートできるので、できることも増えます。
listen




                         DOMイベントと同じ。
                       Bubbling/Capture が利用可能


離れていても同様。DOMイベントと同じく、ルートにあたるインスタンスまでイベントは届きます。
理由その2:関連するインスタンス同士の
   通信が、効率的になる。
3つめ
毎回、レンダーツリーに
             変更を加えていませんか?




3つめの、理由です。
http://jsperf.com/appending-to-render-tree
http://jsperf.com/appending-to-render-tree
for (var i=0; i<10; i++) {
        var component = new goog.ui.Component();
        component.render(); // XXX: Don’t do this!
    }




もしこう書いたら、jsperfの例と同じこと。

毎回レンダーツリーにelementをappendしていってしまっています。
関連するelement(DOMツリー)の
               appendは、1回で。




・・・こう実装すると、確実です。
/** @constructor */
   app.ui.Parent = function () {
      goog.base(this);

        for (var i=0; i<10; i++) {
           this.addChild(new app.ui.Child());
        }
   };

   (‘...’);




まず、親のコンストラクタで、子のインスタンスを生成。
app.ui.Parent.prototype.createDom = function () {
         (‘...’);


         this.forEachChild(function(child) {
             child.createDom();
             dh.appendChild(
                     this.getContentElement(),
                     child.getElement());
         }, this);
    };


次に、親のcreateDom内で、子も一緒にcreateDomし、そのあとにappend先を決定します。
親コンポーネント                            子コンポーネント


       コンストラクタ                            コンストラクタ
                                手動
              ↓
                                            createDom、
         createDom
                                手動      親のelementにappend
              ↓
       enterDocument                       enterDocument
                                自動
              ↓
        exitDocument                       enterDocument
                                自動
              ↓
           dispose                             dispose
                                自動


new と、createDom のみchildの挙動を指定をすれば、あとはgoog.ui.Componentが
親コンポーネントのライフサイクルにそって、子も同じ運命をたどります。
親コンポーネント                子コ


                         コンストラクタ                  コン

                              ↓
                                                      c
     parent.render()      createDom
                                                 親の
      (bodyに、1度だけ
                              ↓
       appendされる)
                         enterDocument                en
                              ↓
                         exitDocument                 en
                              ↓
     parent.dispose()
                            dispose



インターフェースから見る処理の流れは、こんな感じ。

したがって、子は基本的にrenderメソッドを使わない、といえると思います。(もちろん、使うこともでき
る)
理由その3:
          親のcreateDom → 子のcreateDom で、
             安全にDOMを組み立てられ、
          効率よくappendすることができます。




その3まとめ。
parent.addChild(child, true); を使えばいい

(       )
  という方もいるかも知れませんが、
      基本形はこの形で考えます
理由その1:インスタンスのdisposeが、大変になる。


  理由その2:インスタンス同士の通信が、効率的になる。


  理由その3:1回のappendで済む。
             DOM Exception のリスクも減らせる。




以上3点が、「なぜツリー化するのか」の理由です。
ツリー化するメリットが
理解いただけたかと思います
前半:なぜ、goog.ui.Componentを   後半:
             ツリー化すべきなのか?




十分理解していただいたところで。
tを     後半:goog.ui.Componentのはぐれかた
?            ツリー化する上での例外ケース3種類




後半は、この基本形からそれなければいけないケースを、3例、紹介したいと思います。
ツリーの基本形からはぐれる、
 3つのケースを紹介します
goog.ui.Thousandrows を
           ちょっとだけ紹介させてください




まず、1つめを紹介する前に。

僕の作った、Thousandrows について紹介させてください。
• 大量の行を、すぐ表示
   • つなぎ目なしでスクロール(≠ページング)
   • 任意の箇所にジャンプ(≠単なる無限スクロール)




大量の行を効率よく表示できる、UIコンポーネントです。
http://stakam.net/closure/120722/
Page




                                      Row

Thousandrows




コンポーネントの親子関係を築いているので、
rowsのdisposeも効率的にでき、インスタンス間通信もしやすく、
Thousandrowsが一体となって機能することができます。
goog.ui.Component
                             ↓
                      goog.ui.Control

                             ↓
                      goog.ui.Scroller
                             ↓
                   goog.ui.Thousandrows




このThousandrows を作るために、まずScrollerを作りました。継承させています。
Slider

   Scroller




Scrollerは、こういう構造になっています。

ですが、Thousandrowsのようなものを作れるように、Sliderはchildrenに加えるわけにはいきません。
ケース1:関連するインスタンスを、
 childに加えられないことがある
goog.ui.Componentの children は、
       一律で contentElement_ にappendされるべき




Scroller というからには、childをcontentElement に入れていけるべきです。
contentElement_




                  Slider

 Scroller
contentElement_




                                             Slider

   Scroller

                      Scrollerのchildにできない


child は、ユーザーが加えていけるようにするため、空にしておく必要がありました。
• childたちは、contentElement_ に並ぶようにして
     おかないと、 addChildAt が動かなくなる。
     (child.getElement()のsiblingに挿入してる)



   • 異質のcomponentインスタンスをchildrenに
     混ぜると、this.forEachChild しにくくなるので
     おすすめできない。



Slider を、Scroller のchild にできない理由。
Scroller に関連する Slider コンポーネントを、
                 child にできない。




childにできないことがわかった。こんなときは、どうするか?
childにせず、手動で親の
         ライフサイクルに追従させればOK




childにせず、手動で親のライフサイクルに追従させるという手があります。
通常と同じ

/** @constructor */
goog.ui.Scroller = function () {
   goog.base(this);
   (‘...’);

     this.slider_ = new goog.ui.Slider();
};

(‘...’);
通常と同じ


goog.ui.Scroller.prototype.createDom = function () {
  (‘...’);

     this.slider_.createDom();
     this.getElement().appendChild(this.slider_.getElement());
};
通常と違う

    goog.ui.Scroller.prototype.enterDocument = function () {
      (‘...’);

         this.slider_.enterDocument(); // 忘れずに

         this.getHandler().listen(this.slider_, ‘change’, function(e) { });

         //(または、this.slider_.setParentEventTarget(this) してもいいと思う)
    };




child でないので、enterDocument は手動で必要になるので、忘れずに。

あとは、イベントのlistenは、slider をターゲットにして行う必要があります。
setParentEventTarget することも考えられますが、こうするとイベントがパブリックになります。
通常と違う



goog.ui.Scroller.prototype.exitDocument = function () {
  (‘...’);

     this.slider_.exitDocument();  // なくてもいい
};
通常と違う

goog.ui.Scroller.prototype.disposeInternal = function () {
  if (this.slider_) {
      this.slider_.dispose();
      this.slider_ = null;
  }

     (‘...’);
};
ケース1まとめ:childにできない場合、
  手動で状態を変えていくことで
インスタンスを管理しつづけられる。
ケース2:
childを、parnetの contentElement_ 以外に
         appendしたいとき
再び、ちょっと紹介させてください
タブ
tabs
         tab         tab              tab




                              frame




タブのchild は、frameひとつです。でも・・・
tabs
         tab        tab           tab



        childにしたい。。
        でもDOM的にとても距離がある



                          frame




距離がある。tab のDOMにappend することは、考えられない。
append先だけ、変えればOK.
通常と同じ


   /** @constructor */
   app.ui.Tab = function () {
      goog.base(this);

        this.frame_ = new app.ui.Frame();
   };

   (‘...’);




まず、親のコンストラクタで、子のインスタンスを生成しておきます。
通常と違う
  app.ui.Tab.prototype.createDom = function () {
       (‘...’);


       this.frame_.createDom();


       // 別のDOMに入れても問題ない。

       dh.appendChild(
                  App.getInstance().getFrameWrapEl(),
                  this.frame_.getElement());
  };



次に、親のcreateDom内で、子も一緒に
• childを、遠くのDOMにappendしても、特に問題ない
• parentEventTarget として機能、disposeなども
• getContentElement は、通ったらだめ。
 (addChildAt も)




注意点。
ケース2まとめ:
DOM的関係性があまりなくても、
   親子関係は築ける。
ケース3:ライフサイクルを
意図的にずらしたいとき
先ほどの tab と frame の例は
                   忘れて頂いて・・・




ここ。ちょっと雑です。具体例の使いかたが雑なので注意してください。
タブ




もういちど出て来ました。さっきの例は忘れてください。
非選択タブ。frameは、まだレンダリングしてない




タブ自身は、初期表示時にすべてレンダリングされますが、非選択のタブのフレームは、まだレンダリングし
たくない。
親が選択されたときに、
   子をレンダリングしたい。
(意図的にライフサイクルをずらしたい)
通常と同じ


   /** @constructor */
   app.ui.Tab = function () {
      goog.base(this);

        this.frame_ = new app.ui.Frame();
   };

   (‘...’);




まず、親のコンストラクタで、子のインスタンスを生成しておきます。
通常と違う


   app.ui.Tab.prototype.createDom = function () {
        (‘...’);


        // frame はまだレンダリングしない。appendもされない。

   };




createDom で、Tabのelement は作る。frame のelement は作らない。まだいらないから。
通常と違う

  app.controller.Tab.prototype.processSelected = function () {
       (‘...’);


       if (!this.frame_.isInDocument()) {
           this.frame_.render(wrapEl);
       }
  };




・・・タブである自分が選択されたタイミングで、初めてframeをレンダリングします。

append先は、前述したとおり、自由な場所を指定できます。

childにしてあるので、disposeなどは、親と同じときに自動で処理されます。
ケース3まとめ:
必要に応じて、ライフサイクルを
  ずらすことも可能。
•   ケース1まとめ:
    childにできない場合、手動で状態を変えていくことで
    インスタンスを管理しつづけられる。


•   ケース2まとめ:
    DOM的関係性があまりなくても、親子関係は築ける。


•   ケース3まとめ:
    必要に応じて、ライフサイクルをずらすことも可能。
ツリー化のメリットと
基本のライフサイクルを理解したうえで、
柔軟にClosure Libraryからはぐれましょう!
おわり

Más contenido relacionado

Destacado

本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。Teppei Sato
 
コンポーネント指向と余白の設計
コンポーネント指向と余白の設計コンポーネント指向と余白の設計
コンポーネント指向と余白の設計Manabu Yasuda
 
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティスコンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、ReactのベストプラクティスとバッドプラクティスKohei Asai
 
キャッチアップJavaScriptビルド - ビルドから見るJSの今/2016春
キャッチアップJavaScriptビルド -ビルドから見るJSの今/2016春キャッチアップJavaScriptビルド -ビルドから見るJSの今/2016春
キャッチアップJavaScriptビルド - ビルドから見るJSの今/2016春Kondo Hitoshi
 
まだ DOM 操作で消耗してるの?
まだ DOM 操作で消耗してるの?まだ DOM 操作で消耗してるの?
まだ DOM 操作で消耗してるの?Yuki Ishikawa
 
なぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのかなぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのかYoichi Toyota
 
ハードディスクの正しい消去(2015.7)
ハードディスクの正しい消去(2015.7)ハードディスクの正しい消去(2015.7)
ハードディスクの正しい消去(2015.7)UEHARA, Tetsutaro
 

Destacado (11)

Nginx
NginxNginx
Nginx
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。本当のClosure Compilerをお見せしますよ。
本当のClosure Compilerをお見せしますよ。
 
コンポーネント指向と余白の設計
コンポーネント指向と余白の設計コンポーネント指向と余白の設計
コンポーネント指向と余白の設計
 
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティスコンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
コンポーネント指向による、Reactのベストプラクティスとバッドプラクティス
 
キャッチアップJavaScriptビルド - ビルドから見るJSの今/2016春
キャッチアップJavaScriptビルド -ビルドから見るJSの今/2016春キャッチアップJavaScriptビルド -ビルドから見るJSの今/2016春
キャッチアップJavaScriptビルド - ビルドから見るJSの今/2016春
 
まだ DOM 操作で消耗してるの?
まだ DOM 操作で消耗してるの?まだ DOM 操作で消耗してるの?
まだ DOM 操作で消耗してるの?
 
なぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのかなぜ人は必死でjQueryを捨てようとしているのか
なぜ人は必死でjQueryを捨てようとしているのか
 
Angular2実践入門
Angular2実践入門Angular2実践入門
Angular2実践入門
 
Angular1&2
Angular1&2Angular1&2
Angular1&2
 
ハードディスクの正しい消去(2015.7)
ハードディスクの正しい消去(2015.7)ハードディスクの正しい消去(2015.7)
ハードディスクの正しい消去(2015.7)
 

Similar a goog.ui.Component のはぐれかた

GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackTakahiro Yoshimura
 
Webアプリのシナリオテスト自動化を運用に乗せるまでの10のステップ
Webアプリのシナリオテスト自動化を運用に乗せるまでの10のステップWebアプリのシナリオテスト自動化を運用に乗せるまでの10のステップ
Webアプリのシナリオテスト自動化を運用に乗せるまでの10のステップNaoki Iwami
 
Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010Takashi EGAWA
 
Ecmascript2015とその周辺について
Ecmascript2015とその周辺についてEcmascript2015とその周辺について
Ecmascript2015とその周辺について豊明 尾古
 
UI設計におけるスマートフォン対応のまとめ
UI設計におけるスマートフォン対応のまとめUI設計におけるスマートフォン対応のまとめ
UI設計におけるスマートフォン対応のまとめTomoki Imatomi
 
iPhoneアプリ開発の歩き方〜Swift編〜
iPhoneアプリ開発の歩き方〜Swift編〜iPhoneアプリ開発の歩き方〜Swift編〜
iPhoneアプリ開発の歩き方〜Swift編〜Yusuke SAITO
 
おいしいFragment #antama_ws
おいしいFragment #antama_wsおいしいFragment #antama_ws
おいしいFragment #antama_wsTakahiro Yoshimura
 
ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】株式会社ランチェスター
 
20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会Yukihiro Kitazawa
 
I phoneアプリ入門 第4回
I phoneアプリ入門 第4回I phoneアプリ入門 第4回
I phoneアプリ入門 第4回Sachiko Kajishima
 
Vue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとり
Vue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとりVue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとり
Vue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとりYuta Ohashi
 
2010/8/27 TechEd2010 ライトニングトーク
2010/8/27 TechEd2010 ライトニングトーク2010/8/27 TechEd2010 ライトニングトーク
2010/8/27 TechEd2010 ライトニングトークSunao Tomita
 
Kawaz的jQuery入門
Kawaz的jQuery入門Kawaz的jQuery入門
Kawaz的jQuery入門Kohki Miki
 
夜子まま塾講義10(画面の呼び出し)
夜子まま塾講義10(画面の呼び出し)夜子まま塾講義10(画面の呼び出し)
夜子まま塾講義10(画面の呼び出し)Masafumi Terazono
 
Android lecture for iOS developers
Android lecture for iOS developersAndroid lecture for iOS developers
Android lecture for iOS developersMasahiro Morodomi
 

Similar a goog.ui.Component のはぐれかた (20)

GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hack
 
Lt 111119
Lt 111119Lt 111119
Lt 111119
 
Webアプリのシナリオテスト自動化を運用に乗せるまでの10のステップ
Webアプリのシナリオテスト自動化を運用に乗せるまでの10のステップWebアプリのシナリオテスト自動化を運用に乗せるまでの10のステップ
Webアプリのシナリオテスト自動化を運用に乗せるまでの10のステップ
 
OSC京都2011
OSC京都2011OSC京都2011
OSC京都2011
 
Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010Tokyo GTUG Bootcamp2010
Tokyo GTUG Bootcamp2010
 
Ecmascript2015とその周辺について
Ecmascript2015とその周辺についてEcmascript2015とその周辺について
Ecmascript2015とその周辺について
 
UI設計におけるスマートフォン対応のまとめ
UI設計におけるスマートフォン対応のまとめUI設計におけるスマートフォン対応のまとめ
UI設計におけるスマートフォン対応のまとめ
 
iPhoneアプリ開発の歩き方〜Swift編〜
iPhoneアプリ開発の歩き方〜Swift編〜iPhoneアプリ開発の歩き方〜Swift編〜
iPhoneアプリ開発の歩き方〜Swift編〜
 
おいしいFragment #antama_ws
おいしいFragment #antama_wsおいしいFragment #antama_ws
おいしいFragment #antama_ws
 
ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】ちょっと詳しくJavaScript 特別編【悪霊の神々】
ちょっと詳しくJavaScript 特別編【悪霊の神々】
 
20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会20130924 Picomon CRH勉強会
20130924 Picomon CRH勉強会
 
I phoneアプリ入門 第4回
I phoneアプリ入門 第4回I phoneアプリ入門 第4回
I phoneアプリ入門 第4回
 
Vue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとり
Vue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとりVue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとり
Vue.jsでFormをAtomic Designしてみた時のコンポーネント間のデータのやりとり
 
2010/8/27 TechEd2010 ライトニングトーク
2010/8/27 TechEd2010 ライトニングトーク2010/8/27 TechEd2010 ライトニングトーク
2010/8/27 TechEd2010 ライトニングトーク
 
Kawaz的jQuery入門
Kawaz的jQuery入門Kawaz的jQuery入門
Kawaz的jQuery入門
 
夜子まま塾講義10(画面の呼び出し)
夜子まま塾講義10(画面の呼び出し)夜子まま塾講義10(画面の呼び出し)
夜子まま塾講義10(画面の呼び出し)
 
Jetpack Workshop
Jetpack WorkshopJetpack Workshop
Jetpack Workshop
 
emc++ chapter32
emc++ chapter32emc++ chapter32
emc++ chapter32
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
 
Android lecture for iOS developers
Android lecture for iOS developersAndroid lecture for iOS developers
Android lecture for iOS developers
 

goog.ui.Component のはぐれかた