Marionette.Viewクラス の使い分け

※ サンプルコードは、`coffeescript`、テンプレートは`hamlc`を使用しています。

# View の種類
`ItemView`, `CollectionView`, `CompositeView`, `LayoutView` の4つで、それぞれ`Marionette.View`を継承している。

# ItemView
1つのアイテムを表し、たいてい1つのModelと紐づかせる。

**Templateを使用しない場合**

```coffeescript
template: false
```

# CollectionView
複数のItemViewを管理するView。自身をレンダリングすると、管理しているItemViewもすべてレンダリングする。

### 自動レンダリング機能

CollectionViewは、`add`,`remove`,`reset`のイベントをリッスンしている。

* CollectionViewに紐づいているCollectionが`reset`された場合、自身を再度レンダリングする。

* CollectionViewに紐づいているCollectionにModelが`add`された場合、そのModelと紐づいているChildViewをレンダリングする。

* CollectionViewに紐づいているCollectionにModelが`remove/destroy/delete`された場合、そのModelと紐づいているChildViewを除去する。

**管理するItemViewの定義**

```coffeescript
childView: ItemViewのクラス
```

**管理するItemViewを動的に変更する場合**

```coffeescript
getChildView: (model)->
  if model.get('isFoo')
    FooView
  else
    BarView
```

**ChildViewのレンダリングを操作する**
※ デフォルトでは、 jQueryの`append`メソッドが呼ばれ、Collection viewの要素の最後に追加される。

```coffeescript
attachHtml: (collectionView, childView, index) ->
  collectionView.$el.append childView.el
```

**CollectionViewからChildViewにデータを渡す場合**

```coffeescript
childViewOptions:
  foo: "bar"
```

**ChildViewがなかった時に表示するView**

```coffeescript
emptyView: 表示するViewクラス
```

**ChildViewを操作する**

```coffeescript
# ループ
@children.each (childView)->
  ...

# 検索
model = @children.findByModel model

```

# CompositeView
CollectionViewを拡張したもので、ItemViewとCollectionViewを合わせて1つのViewとして扱うことでツリー構造を表現できる。

```coffeescript
class MyCompositeView extends Marionette.CompositeView
  className: 'クラス名'
  tagName: 'タグ名'
  template: 'テンプレート'
  childView: 'ItemView'
  childViewContainer: 'ItemViewを包む要素'
  initialize: ->
    @collection = new SomeCollection(someJson)
```

model、collectionを両方持つことができる。collectionをセットしておくと、自身のレンダリング時に childView もレンダリングすることが可能。

# LayoutView
regionを扱えるItemView。

```coffeescript
class MyLayoutView extends Backbone.Marionette.LayoutView
  regions:
    Header: 'header'
    Section: 'section'

  onShow: ->
    @Header.show new HeaderView
    @Section.show new SectionView
```

※ LayoutViewを再レンダリングすると、強制的に中身が空になってしまう。LayoutViewを再レンダリングするのはなるべく避けた方がいいらしい。

※ LayoutViewの下にさらにLayoutViewがある場合に、親のLayoutでshowを走らせると、下のLayoutViewでshowする時に、すでに破棄されているのでエラーになる。

## その他の使い分け

* CollectionViewの中でさらにCollectionViewを表示する場合は、`CompositeView` または `LayoutView` のどちらかを使用する。

* CollectionViewの中でさらに2つ以上のCollectionViewを表示する場合は、`LayoutView`を使用する。

# Marionette.View
ここで定義されているメソッドは、どのViewクラスからも呼び出すことができる。

**ui**: HTML要素定義し、jQueryオブジェクトとして扱うことができる。

```coffeescript
ui:
  checkbox: "input[type=checkbox]"

onRender: ->
  @ui.checkbox.addClass 'checked'
```

**modelEvents/collectionEvents**: 紐づいているModel/Collectionの状態が変化したときに発生するイベント。

```coffeescript
modelEvents:
  'change':'modelChanged'
  'change:name':'modelNameChanged'
collectionEvents:
  'add':'itemAdd'

modelChanged: ->
  alert 'modelChanged'

modelNameChanged: ->
  alert 'modelNameChanged'

itemAdd: ->
  alert 'itemAdd'
```

**onShow**: RegionでshowされたViewに対して発生する。呼ばれるタイミングは、レンダリングされて画面に表示された後。ChildViewを表示する時によく使う。

※ 上記`LayoutView`参照

**templateHelpers**: ViewからTemplateに対して、変数や関数を提供できる。

```coffeescript
templateHelpers: ->
  name: '鈴木' 
  doSomething: ->
    ...

```
↓
`templates.hamlc`

```haml
= @name # "鈴木"が参照できる

= @doSomething() # 関数実行
```

**getTemplate**: Templateを動的に変更する。

```coffeescript
getTemplate: ->
  if @model.get("foo")
    "#some-template"
  else
    "#a-different-template"
```