###前提・実現したいこと
Backbone.js初学習者です。
JavaScript(jQuery)でコーディングしていたのですが、結構な量のDOM操作とAjax通信になってきたため、そのような状態からでも導入できそうなフレームワークを探していたところ、Backbone.jsにたどり着きました。
そこで、Backbone.js導入の第一歩として、以下のような処理を実装しよう試みました。
①id="btn-get-size"のボタンをクリック
②idをもとにxmlファイルからサイズ(数値)を取得し、そのサイズを描画する
③描画されたサイズをクリックするとchosenプロパティが変化し、activeクラスが付与され、色が変化する
④その状態でほかのボタンをクリックするとそのサイズにactiveクラスが付与され、先ほどクリックしたサイズの色が消える(つまり、クリックしたサイズ以外は色変化させたくないということです)
上記の中で問題となっているのが③、④です。同じサイズを連続でクリックした場合は色が消えないようにしたいのです。
(簡単に言うと、色がつくのはクリックしたものだけ。ということです)
私の書いたコードですと、同じものをクリックすると色が消えてしまいます。(当たり前といえば当たり前なのかもしれませんが...)
個人的な考えでは、「サイズがクリックされたとき描画されている全モデルのchosenプロパティをfalseにし、その後でクリックしたもののchosenプロパティをtureにし、renderしなおす。」
という方法で実現できるのではないかと考えているのですが、Backbone.jsでそれをどう記述してやればいいのかがわかりません...
(そもそもBackbone.jsを使っていて、$(".size-selector").find(".btn-size").removeClass("active"); などとしている時点でかなりナンセンスですよね...)
どなたか、解決策を教えていただけると非常に助かります_(..)
###該当のソースコード
javascript
1(function(){ 2 //Model 3 var Size = Backbone.Model.extend({ 4 defaults: { 5 size: "", 6 chosen: false 7 } 8 }); 9 10 //Collection 11 var Sizes = Backbone.Collection.extend({ 12 model: Size 13 }); 14 15 //ModelのView 16 var SizeView = Backbone.View.extend({ 17 tagName: 'li', 18 template: _.template($('#size-template').html()), 19 initialize: function(){ 20 this.model.on('change', this.render, this) 21 }, 22 events: { 23 'click .btn-size': 'toggle' 24 }, 25 toggle: function(){ 26 //ここで全部falseにする必要あり? 27 $(".size-selector").find(".btn-size").removeClass("active"); 28 29 if (this.model.get('chosen') == false) { 30 this.model.set('chosen', true); 31 } 32 else { 33 this.model.set('chosen', false); 34 } 35 }, 36 render: function(){ 37 var template = this.template(this.model.toJSON()); 38 this.$el.html(template); 39 return this; 40 } 41 }); 42 43 //CollectionのView 44 var SizesView = Backbone.View.extend({ 45 tagName: 'ul', 46 render: function(){ 47 this.collection.each(function(size){ 48 var sizeView = new SizeView({model: size}); 49 this.$el.append(sizeView.render().el); 50 }, this); 51 return this; 52 } 53 }); 54 55 //ボタンのView 56 var ShapeBtnView = Backbone.View.extend({ 57 el: '#show-size', 58 events: { 59 'click #btn-get-size': 'getSize' 60 }, 61 getSize: function(){ 62 //シェイプidを付与 63 SHAPE.id = 'test01'; 64 //サイズCollectionを生成 65 var sizes = new Sizes(); 66 67 ajax_processing('size.xml', function(xml){ 68 $(xml).find('shape[code="' + SHAPE.id + '"] > SizeList > Size').each(function(){ 69 //サイズ格納 70 var size = $(this).attr('size'); 71 72 //取得したサイズをプロパティに設定して、sizeインスタンスを生成 73 var size = new Size({size: size, chosen: false}); 74 75 //sizeをCollectionに追加 76 sizes.add(size); 77 }); 78 //Collectionをrender 79 var sizesView = new SizesView({collection: sizes}); 80 $('.size-selector').append(sizesView.render().el); 81 }); 82 } 83 }); 84 85 //インスタンス生成 86 var shapeBtnView = new ShapeBtnView(); 87})(); 88
html
1<div id="show-size"> 2 <button type="button" id="btn-get-size" class="btn btn-primary">Size一覧表示</button> 3</div> 4<h3>Backbonejs Demo</h3> 5<div class="size-selector"> 6 <!-- ここに挿入 --> 7</div> 8 9<script type="text/template" id="size-template"> 10 <div class="btn-size <%= chosen ? 'active' : '' %>"> 11 <%- size %> 12 </div> 13</script>
###追記
ajax_processing関数とは以下のようなものです。
javascript
1function ajax_processing(url, fn) { 2 $.ajax({ 3 url: url, 4 type: "GET", 5 dataType: "xml", 6 timeout: 1000, 7 error: function(){ 8 alert("ロード失敗"); 9 }, 10 success: fn 11 }); 12} 13
###追記2
追記2のようにSizesViewのコードを修正したところ、chosenプロパティがtrueのものをfalseにして、renderし直すことはできました。
おそらく、追加したhogeメソッドの中で、クリックされたmodelのchosenプロパティをtrueにしてrenderし直すことができれば、考えていたことが実現できそうなのですが…
javascript
1var SizesView = Backbone.View.extend({ 2 tagName: 'ul', 3 events: { 4 'click .btn-size': 'hoge' 5 }, 6 hoge: function(){ 7 var sizes = this.collection.where({'chosen': true}); 8 _.each(sizes, function(size){ 9 size.set('chosen', false); 10 var sizeView = new SizeView({model: size}); 11 sizeView.render(); 12 }); 13 }, 14 render: function(){ 15 this.collection.each(function(size){ 16 var sizeView = new SizeView({model: size}); 17 this.$el.append(sizeView.render().el); 18 }, this); 19 return this; 20 } 21 }); 22
###追記3
何度も追記してすみません。
実現したいこととしては、下記サイトのようなことです。
しかし、CoffeeScriptがさっぱりなのと、このような複雑そうなことをしなければならないのか疑問で…
Backbone.jsでUIの状態を管理するみたいなやつ
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。