3

**更新:「名前」属性が未定義であると考えていることを発見したため、問題はおそらくツアーテンプレートに関係しています。これは、ToursView に渡される配列ではなく、何らかの理由で文字列であると考えるように導きます。**

StackOverflow で同様の質問を調べた後:

Backbone.Marionetteを使用してネストされたCompositeViewを処理するには?

モデルのjavascript配列プロパティに基づいてバックボーンマリオネットコレクションビューを正しく表示するにはどうすればよいですか?

Backbone.Marionette を使用したネストされたコレクション

... そして、このテーマに関する Derick Bailey の優れたブログ:

http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/

... JSFiddle を含む:

http://jsfiddle.net/derickbailey/AdWjU/

CompositeViews の入れ子になった CollectionView の最後のノードを表示するのにまだ問題があります問題を引き起こしているのは、各 CompositeView 内の最終的な CollectionView です。

CollectionView {
    CompositeView{
        CollectionView {} //**<-- This is the troublemaker!**
        }
    }

注: 最終的な子 CollectionView に渡されるコレクションが単純な配列であることを考慮して、有効な Backbone.Collection を作成することを既に強調しました。

API から ToursList に返されるデータ:

[
{   "id": "1", 
    "name": "Venice", 
    "theTours": "[
        {'name': u'test venice'}, 
        {'name': u'test venice 2'}
    ]"
}, 

{   "id": "2", 
    "name": "Rome",
    "theTours": "[
        {'name': u'Test rome'}
    ]"
}, 
{   "id": "3", 
    "name": "Dublin", 
    "theTours": "[
        {'name': u'test dublin'}, 
        {'name': u'test dublin 2'}
    ]"
}
]

これらを、nav ヘッダーが「name」(つまり Dublin) であるドロップダウンにネストしようとしています。その後の li は個々のツアー名です (つまり、「test dublin」、「test dublin2」など)。

ツアーモデルとコレクション

Tour = TastypieModel.extend({});

ToursGroup = TastypieCollection.extend({
  model: Tour
});

ToursByLoc = TastypieModel.extend({});

ToursList = TastypieCollection.extend({
  model: ToursByLoc,
  url:'/api/v1/location/',
});

ツアービュー

TourView = Backbone.Marionette.ItemView.extend({
  model: Tour,
  template: '#tour-template',
  tagName: 'li',    
});


ToursByLocView = Backbone.Marionette.CompositeView.extend({
  collection: ToursByLoc,

  template: '#toursByLoc-template',
  itemView: TourView,
  itemViewContainer: '#ind',

  initialize: function(){
    //As per Derick Bailey's comments regarding the need to pass on a
    //valid Backbone.Collection to the child CollectionView
    //REFERENCE: https://stackoverflow.com/questions/12163118/nested-collections-with-backbone-marionette

    var theTours = this.model.get('theTours');
    this.collection = new ToursGroup(theTours);
    console.log(this.model.get('name'));
    console.log(theTours);
    //To test the output --> I get:

    //Venice
    //[{'subtitle': u'ex. These prices include... but not...', 'description': u'Please enter the tour description here', 'start_time': datetime.time(2, 34, 24), 'adult_price': Decimal('123'), 'important': u'ex. Please contact us to negotiate a price if you want to book the Fiat for 1 person only.', 'teenager_student_price': Decimal('123'), 'child_price': Decimal('123'), 'under_6_price': Decimal('123'), 'location_id': 1, 'id': 1, 'name': u'test venice'}, {'subtitle': u'ex. These prices include... but not...', 'description': u'Please enter the tour description here', 'start_time': datetime.time(20, 4, 57), 'adult_price': Decimal('222'), 'important': u'ex. Please contact us to negotiate a price if you want to book the Fiat for 1 person only.', 'teenager_student_price': Decimal('222'), 'child_price': Decimal('222'), 'under_6_price': Decimal('222'), 'location_id': 1, 'id': 2, 'name': u'test 2'}] main.js:64

    //Rome
    //[{'subtitle': u'ex. These prices include... but not...', 'description': u'Please enter the tour description here', 'start_time': datetime.time(1, 28, 25), 'adult_price': Decimal('123'), 'important': u'ex. Please contact us to negotiate a price if you want to book the Fiat for 1 person only.', 'teenager_student_price': Decimal('333'), 'child_price': Decimal('333'), 'under_6_price': Decimal('333'), 'location_id': 2, 'id': 3, 'name': u'test rom1'}] main.js:64

    //Dublin
    //[] 

    this.collection = new ToursGroup(theTours);
  }
});

ToursListView = Backbone.Marionette.CollectionView.extend({
  itemView: ToursByLocView,
});

テンプレート

  <script id="tour-template" type="text/template">
    <%= name %> //<-- THIS IS GIVING ME ISSUES
  </script>

  <script id="toursByLoc-template" type="text/template">
    <li class="nav-header"><%= name %></li>
    <div id="ind" class="indTours"></div>
    <li class="divider"></li>
  </script>

  <script id="tours-template" type="text/template">
    <%= name %>
  </script>
4

1 に答える 1

4

これは問題ではないと思いますが、次のように変更する必要があります。

itemViewContainer: '#ind'

CompositeView 定義で。これは悪い/無効です/説明できない結果が生じる可能性があります。DOM は、特定のid. この場合、<div id="ind"></div>すべての CompositeView インスタンスがあります。

itemViewContainerこれを CSS クラスに変更し、代わりにクラス セレクターを使用する必要があります。

...

私はあなたのコードで JSFiddle を構築しました

アプリでどのような結果が得られますか? 代わりに何を見ることを期待していますか?

...

データが戻ってくる様子を見てください。


    "theTours": "[
        {'name': u'test venice'}, 
        {'name': u'test venice 2'}
    ]"

これは技術的に有効な JSON ですが、実際の配列ではなく、配列のように見える文字列を返します。

私の JSFiddle では、これを修正する必要がありました。


    "theTours": [
        {'name': 'test venice'}, 
        {'name': 'test venice 2'}
    ]

[ ] の周りの " と " を削除し、文字列値の前にある "u" も削除したことに注意してください。

サーバーがデータを JSON ドキュメントに不適切にシリアル化し、この不適切な形式のドキュメントを送り返している可能性があります。

于 2012-11-30T04:28:16.290 に答える