Backbone显示嵌套的json集合

时间:2013-12-17 17:36:11

标签: javascript json backbone.js

不知道我哪里错了。我似乎无法获取模板来在嵌套的json中呈现标题属性。我正在按照一个在线教程,有点牵着我的手,但我碰到了一堵砖墙,无法弄清楚它为什么不会渲染。任何帮助将不胜感激。

这是我的模板和HTML。

  <script id="albumTemplate" type="text/template">
     <p><%= title %></p>
  </script>
  <script id="subalbumTemplate" type="text/template">
     <p><%= title %></p>
  </script>

  <div class="row">
     <div class="six columns"><h5>Albums</h5></div>
     <div class="six columns"><h5>Sub-Albums</h5></div>
  </div>
  <div class="row" style="color: #333;">
     <div class="six columns" id="categories"></div>
     <div class="six columns" id="sub-cat"></div>
  </div>

这是我的app.js

        app.Subalbum = Backbone.Model.extend({
            initialize: function () {
                this.subId = this.get('id');
                this.subTitle = this.get('title');
                this.subImg = this.get('image');
                this.subCanvas = this.get('canvas');
                this.subSize = this.get('size');
            }
        });
        app.Subalbums = Backbone.Collection.extend({
            model: app.Subalbum
        });
        app.Album = Backbone.Model.extend({
            initialize: function () {
                this.subs = new app.Subalbums(this.get('subalbum'));
                this.subs.parent = this;
                this.albumId = this.get('id');
                this.albumTitle = this.get('title');
                this.albumImg = this.get('image');
            }
        });
        app.Albums = Backbone.Collection.extend({
            model: app.Album,
            url: 'albums.json',
            parse: function (data) {
                return data;
            }
        });

        app.AlbumCollectionView = Backbone.View.extend({
            el: $("#categories"),

            initialize: function () {
                _.bindAll(this, 'render');
                this.model.on('reset', function () {
                    this.render();
                }, this);
            },

            render: function (event) {
                _.each(this.model.models, function (album) {
                    //console.log(album.subs);
                    $(this.el).append(new app.AlbumView({
                        model: album
                    }).render().el);
                }, this);
                return this;
            }
        });

        app.AlbumView = Backbone.View.extend({
            template: _.template($("#albumTemplate").html()),
            initialize: function () {
                _.bindAll(this, 'render');
                // Subalbum View should be instantiated and called from inside the initialize function of the Parent View
                this.subView = new app.SubalbumView({
                    model: this.model.subs
                });
                this.subView.parentView = this; // this assignment connects the child view to the parent view
                $("#sub-cat").append(this.subView.render().el); // subView should "return this" from child render() function
            },
            render: function () {
                //console.log(this.model.subs);
                //$(this.el).html("<p>" + this.model.get("title") + "</p>");
                $(this.el).append(this.template(this.model.toJSON()));
                return this;
            }
        });

        app.SubalbumView = Backbone.View.extend({
            template: _.template($("#subalbumTemplate").html()),
            initialize: function () {
                _.bindAll(this, 'render');
                this.model.on('reset', function () {
                    this.render();
                }, this);
            },

            render: function (event) {
                _.each(this.model.models, function (subalbum) {
                    $(this.el).append("<p>" + subalbum.get("title") + "</p>");
                    //$(this.el).html(this.template(subalbum.toJSON()));
                }, this);
                return this;
            }
        });

        app.AlbumRouter = Backbone.Router.extend({
            routes: {
                "": "indexRoute"
            },
            indexRoute: function () {
                this.albumList = new app.Albums();
                this.albumList.fetch();
                this.albumAppView = new app.AlbumCollectionView({
                    model: this.albumList
                });
            }
        });

        var albumRoute = new app.AlbumRouter();
        Backbone.history.start();

这是albums.json文件结构。

[
   {
      "pid":0,
      "title":"Blues Singer",
      "image":"blues_singer.jpg",
      "subalbum":[
         {
            "pid":0,
            "title":"Another Realm",
            "image":"another_realm.jpg"
         },
         {
            "pid":1,
            "title":"Ascendant",
            "image":"ascendant.jpg"
         },
         {
            "pid":2,
            "title":"Ascent",
            "image":"ascent.jpg"
         }
      ]
   },
   {
      "pid":1,
      "title":"Destiny",
      "image":"destiny.jpg",
      "subalbum":[
         {
            "pid":0,
            "title":"Cathedral of Trees",
            "image":"cathedral_of_trees.jpg"
         },
         {
            "pid":1,
            "title":"Come Up Here",
            "image":"come_up_here.jpg"
         },
         {
            "pid":2,
            "title":"Crystal Forest",
            "image":"crystal_forest.jpg"
         }
      ]
   },
   {
      "pid":2,
      "title":"Eagle",
      "image":"eagle.jpg",
      "subalbum":[
         {
            "pid":0,
            "title":"Curved Road",
            "image":"curved_road.jpg"
         },
         {
            "pid":1,
            "title":"Dawn Breaking",
            "image":"dawn_breaking.jpg"
         },
         {
            "pid":2,
            "title":"Dawn",
            "image":"dawn.jpg"
         }
      ]
   },
   {
      "pid":3,
      "title":"Evening Harvest",
      "image":"evening_harvest.jpg",
      "subalbum":[
         {
            "pid":0,
            "title":"Destiny",
            "image":"destiny.jpg"
         },
         {
            "pid":1,
            "title":"Destiny2",
            "image":"destiny2.jpg"
         },
         {
            "pid":2,
            "title":"Eagle Rising",
            "image":"eagle_rising.jpg"
         }
      ]
   }
]

1 个答案:

答案 0 :(得分:1)

问题是您等待来自reset的{​​{1}}事件,但默认情况下不会触发this.albumList.fetch(),因此您需要将reset传递给{ {1}}。这是JSFIDDLE

{reset:true}

一些建议(我将选择你的fetch),但同样适用于你的其他观点:

  1. 您可以只使用字符串indexRoute: function () { this.albumList = new app.Albums(); // This view will render when the model's reset event is triggered. // Since albumList is a collection, it should identified as such. this.albumAppView = new app.AlbumCollectionView({ // albumList is a collection and it should identified as such. // instead of model:this.albumList - now within albumAppView, you will have // access to the collection via this.collection instead of this.model collection: this.albumList }); this.albumList.fetch({reset:true}); }

  2. 而不是AlbumCollectionView
  3. el: $("#categories")中,当您可以利用listenTo时,您正在使用el:'#categories'。使用initialize的主要优点是在视图上调用this.model.on时,会为您清理事件侦听器。

    listenTo
  4. 转到remove函数后,// this works. this.collection.on('reset', function () { this.render(); }, this); // can be written as (remember the we changed model to collection above). this.listenTo(this.collection,'reset',this.render); 附加了underscore methodsrender

    Backbone.Collection
  5. // while this works _.each(this.collection.models, function (album) { ... }); // can be written as: this.collection.each(function(album) { ... }); }); ,有点过时了,您可以使用$(this.el),它只是视图元素的缓存jQuery对象。 $el documentation

  6. 所以,当我们把它们放在一起时,最终会结束:

    this.$el