BLOG開発関係のメモこの広告は、90日以上更新していないブログに表示しています。javascript(この資料は、社内のBackbone入門の勉強会の為に作った物の下書きです。)これから、Backbone.Viewについての入門記事を書きます。内容としては、Backboneを初めて学ぶ人の為の噛み砕いた入門記事にするつもりです。基本的な使い方は、ModelやCollectionと一緒です。流れとしては、Backboneのコンポーネントをextendした物を宣言して、必要な時にnewしていくという形になります。PostViewBackbone.Viewの役割Backbone.Viewの役割は、まとめると以下の通りです。役割htmlを描写するDOMと関数を紐づけるModel/Collectionと紐づけるこれらについて、それぞれ1つずつ見ていきたいと思います。役割1:htmlを描写するhtmlを描写するには、render関数を使います。renderここに、どんなソースを書いても良いのですが、一般的には、templateを準備してこれを描写するという事がよく行われます。generatorで作ったソースの一部です。全部試したい方は、gistに書いたのでご参考に。他の言語やフレームワークを触った事がある人は、このソースを見たら大体想像が付くと思いますが、一応、簡単に説明をしたいと思います。(なんとなく分かる方は読み飛ばして下さい)別fileとして存在する静的なtemplateを準備しておきます。これは、呼ばれる迄画面に出る事はありません。この定義があった後で、Backbone.Viewのrender()の中からこのtemplateの呼び出しが行われます。この時、値を受け渡す事が出来て、これをキーに紐づけると、templateの中の同名のキーの中にその値が出力されます。※よくBackboneではModelのtoJSONやattributesを渡して、そのキーをtemplateで書いておき、その値を表示させる事をします。最後に、実際のhtmlとして出力します。templateここでは、handlerbars.jsを使いました。templateは、多くの種類から自由に選ぶ事が出来ます。今日、よく聞く選択肢として以下の物があるでしょう。ejshandlebarsmustache以下の比較記事を見ると良いかと。参考http://www.infiniteloop.co.jp/blog/2013/02/js-template-engine/elBackboneのViewで独特でやっかいなのが、elという要素です。これは、このViewが紐づくDOM要素のセレクタを指定するためのプロパティです。Viewがnewされる際に、$elに、elに指定したセレクタを元に取得した要素を格納します。この後、説明していくEventや、View内の$等は、全部、$elに対して実施する操作になります。elの指定のない場合elは指定しない事もできます。その時、$elに、tagNameやidの指定値を元にDOM要素を作り出して格納します。tagNameの指定が無ければ、勝手にdivタグの要素を作成します。これは、実際のhtmlと結びついていない状態になりますので、どこかで、この紐付きを書いてあげる必要があります。$('body').html(view.render().$el);View自体は、elが無いだけで、特に変化はありません。Viewを呼び出す所を見てみると、render()の後に、$elが付いています。これで、このelの指定が無いViewで作成されたDOM要素を取り出してます。thisを書かないといけません。これは、何故かというと、別のViewからel要素を取り出したい時があるためです。上のel指定のないViewソースがそのシチュエーションに該当します。renderがthisを返しているから、render().$elしてDOM要素が取れるのです。役割2:DOMとEventを紐づける次にDOMとEventの紐付きについて見ていきましょう。Backbone.Viewは、こういった混乱をおさえるために、DOMとEventと関数の紐付きを書く所を決めています。この決まった所に書く事で、どこのDOMで、どんなイベントに、どのような処理を任せたいのかが明確になります。これも例を見てみましょう。});Eventsの中にplainなjsのオブジェクトを書きます。それぞれ、イベントとDOMセレクタを記載します。値としては、このイベントで実行したい関数名を書きます。?とても、直感的なルールではないでしょうか?thisについて勘の良い人は、ここで呼ばれた関数のthisコンテキストはどうなるのか、気になる人がいらっしゃるかもしれません。以前のversionのBackboneでは、ここで呼ばれる関数のthisを自分でbindする必要がありました。最近のBackboneは、このbind処理が本体に入っているので、特に意識する必要はありません。※ただし、events内の指定以外の所で、callbackから呼び出す関数等のbindingは自分で書く必要がありますので、注意して下さい。Viewを書く時によくあるのですが、Event書いたのにうまく実行されない事があります。その時は、以下をチェックしましょう。elが存在するのか?eventで指定した要素がelの配下に存在するのか?$elに対して、イベントのbindをしているので、elが実際のhtmlに存在しなかったり、elの中に無い要素だとうまくいきません。役割3:Model/Collectionと紐づけるBackboneのViewはModelを監視して、状態変化に伴い処理を実行します。これを書くために、Viewには、ModelやCollection用のプロパティが準備されています。実際の使われ方としては、以下の様な流れになる事が多いでしょう。Viewをnewする時に、model(collection)を指定View内のinitializeで、modelに対してeventをbinding何かしらのmodelの状態変化があれば、上記のbindingを辿って関数を実行この時、最後の関数へのthisのbindingは自分で書く必要があるので、忘れないようにしましょう。'seconds');データバインディングさて、modelやcollectionとの紐付けについて、基本的な話から少し脱線したいと思います。最近、Angularjsの勢いが激しく、非常に活発になってきました。AngularjsとBackboneの違いでよく出てくるのが、データバインディングの有無です。Backbone本体にはデータバインディングが無いので、一見劣っているように見えますが、実は、プラグインを入れると簡単に使う事が出来ます。実際に実装する時に、データバインディングがあるかないかでソースの量が大分違うので、簡単に見てみましょう。stickitNYTimes社のpluginです。使い方がとてもsimpleで良いので、見てみましょう。http://lxyuma.hatenablog.com/entry/2013/11/07/233930※ここは後で書く。実装パターンViewを書く上で非常に頻繁に出て来るシチュエーションが、親子階層を伴うViewです。最後に、このパターンについて見てみましょう。親子ViewBackboneで開発していると、どうしても、親子の階層を持つViewを書く必要が出てきます。ここでいう「親子の階層を持つView」とは、例えば、ulタグが親のViewでliタグが子供のViewであるような階層を持ったViewの事です。このViewを親子の階層に分ける必要があるのでしょうか?もし、1つのViewでこの親子階層を表現しようとすると、毎回、どのViewがどのModelを指すのかの紐付け処理を書く必要がでてきます。最悪、htmlの属性要素にカスタム属性を入れなくてはならず、せっかくjavascriptのframeworkを使っているのにスマートな形ではありません。そこで、親と子供のそれぞれをViewとして分離して、1つの子供Viewのインスタンスが、elとmodelを紐づけて持っておき、Eventに対応した処理もそのViewの中でやってしまう事で非常にsimpleでスマートな実装にする事ができるのです。実際これをソースで書くと結構面倒くさい事になります。親から見て子供の追加があったら関数A、削除があったら関数B、等々毎回同じソースを書く事になり、また、書き方も沢山あるので、場合によっては非常に複雑なソースが出来てしまいます。そこで、MarionetteのCollectionViewとItemViewが使えます。最後に一通り、Viewがどんなものか分かった所で、是非、ソースを読んでみると良いと思います。Backbone.Viewが恐ろしくsimpleで、非常にソース行数が少ない事に驚くと思います。細かな動き等は、適宜Backbone.Viewを見て確かめる事をお勧めします。