Marionette.jsのitemViewに追加されるdivを消す方法



色々便利なMarionette.jsなのですが、CollectionViewに配列を入れてrenderした場合に、itemvViewにClass名を指定しておかないと、divが入ってしまいます。

これによって、CSSが崩れてしまったりtableがおかしくなってしまったりすることがあると思います。
今回はこれの対処方法について書いていきます。

Marionette.js使っているdivが入ってムキーってなる!

この現象なのですが、BackboneやMarionette.jsを使っていると結構起きたりなったりしませんか?ItemViewにタグを設定出来るのですが、設定しないとdivが入ってしまし、なんだかわけわからない入れ子になってしまったりします。

例えばこんなシチュエーションです。

実装例

例えば、リストを作る場合のソースはこんな感じになると思います。
※パッと書いたので、あまり正確じゃないかもしれないです…

まずはjs側

[javascript]

var listItemView = Marionette.ItemView.extend({
tagName:"li",
template:"#listTmpl"
});

var listCollectionView = Marionette.CollectionView.extend({
childView:itemView,
el:"#listOutput"
});

var collectionView = new listCollectionView({
collection: new Backbone.Collection([
{name: "foo"},
{name: "bar"},
{name: "hoge"}
])
});

[/javascript]

で、テンプレートはこんな感じで、

[html]

<script type="text/html" id="itemTemplate">
<%- name %>
</script>

[/html]

最終的な出力はこんな感じになると思います。

[html]

<ul id="#listOutput">
<li>foo</li>
<li>bar</li>
<li>hoge</li>
</ul>

[/html]

これだけ見ると、なんと使いやすいんだろうと思うんですが、こんな場合だと困ります。

問題になる例

例えばこんな場合にうまくいきません。

[html] <ul id="#listOutput">
<li data-listName = "foo">foo</li>
<li data-listName = "bar">bar</li>
<li data-listName = "foo">hoge</li>
</ul>
[/html]

直感的に考えれば、テンプレートを

[javascript] <script type="text/html" id="itemTemplate">
<li data-listName = "<% name %>"><%- name %></li>
</script>
[/javascript]

とすれば行けそうな気がしますが、実際の出力結果を見てみると

[html] <li><li data-listName = "foo">foo</li></li>
<li><li data-listName = "bar">bar</li></li>
<li><li data-listName = "foo">hoge</li></li>
[/html]

となってしまいます。じゃ、viewのtagNameをとれば!とすると今度はこんな感じになります

[html] <div><li data-listName = "foo">foo</li></div>
<div><li data-listName = "bar">bar</li></div>
<div><li data-listName = "foo">hoge</li></div>
[/html]

div〜〜〜〜〜〜〜〜。。。

なんでそこに入るんだよ〜

対処方法

これを対処するにはこれを生成している、ItemViewがRenderされる際に、そのdivを消してしまえばいいんです。

それを実装したitemViewはこんな感じ↓

[javascript]

var listItemView = Marionette.ItemView.extend({
tagName:"li",
template:"#listTmpl",
onRender:function(){
this.$el = this.$el.children();
this.$el.unwrap();
this.setElement(this.$el);
}
});

[/javascript]

これで思ったとおりの実装になったと思います。

まとめ

全体的にはMarionette.jsって便利なんですけど、こういうところにたまにイラッとします…




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

ABOUTこの記事をかいた人

Web Developer & Web Designer at Yahoo! Japan. Like HTML, css, JavaScript, Apple, ra-men, Angular, b-monster.