骨干直接网址访问打破了收集

时间:2012-06-27 12:40:54

标签: jquery backbone.js

当用户转到http://example.com/#/playlist时,我想列出一些歌曲。

当您第一次访问http://example.com并点击<a href="#/playlist">Playlist</a>链接时,它可以正常播放(列出所有歌曲)。

但如果您直接转到http://example.com/#/playlist,则不会显示任何内容。

当我记录this.collection属性时,该集合始终是相同的(如果您使用该链接,或直接访问)。

唯一的区别是下面的render-function中的this.collection.each( function ( song ) {} );在直接访问URL时不会循环。

这是代码:

define(
    [
        'jQuery',
        'Underscore',
        'Backbone',
        'collections/songlist',
        'views/song'
    ],

    function ($, _, Backbone, SonglistCollection, SongView)
    {
        var PlaylistView = Backbone.View.extend({

            // properties
            el: '#content',
            tagName: 'ul',
            collection: new SonglistCollection(),

            /**
             * Initialize
             */
            initialize: function()
            {
                // load songs
                this.collection.bind( 'reset', this.render(), this );
                this.collection.fetch();
            },

            /**
             * Render
             */
            render: function ()
            {
                this.$el.html('');

                console.log(this.collection);

                this.collection.each( function ( song )
                {
                    var songItem = new SongView( { model: song } );
                    this.$el.append( songItem.el );

                }, this);
            }

        });

        return new PlaylistView;

    }
);

问题出现在' each-loop '中:

render: function ()
                {
                    this.$el.html('');

                    console.log(this.collection);

                    this.collection.each( function ( song )
                    {
                        var songItem = new SongView( { model: song } );
                        this.$el.append( songItem.el );

                    }, this);
                }

更新

这是我的路由代码:

define([
    'jQuery',
    'Underscore',
    'Backbone',
    'views/start',
    'views/playlist'
],

    function ($, _, Backbone, startView, playlistView)
    {
        var AppRouter = Backbone.Router.extend({
           routes: {
               'playlist': 'playlist',

               // default
               '*actions': 'start'
           },

           start: function ()
           {
               // call render on the module we loaded via the dependency array
               // views/items/list
               startView.render();
           },

            playlist: function ()
            {
                playlistView.render();
            },

            defaultAction: function ( actions )
            {
                // no default action, let's just log what the url was
                console.log('No route:', actions)
            }
        });

        var initialize = function ()
        {
            var app_router = new AppRouter;
            Backbone.history.start();
        }

        return {
            initialize: initialize
        };
    }

);

3 个答案:

答案 0 :(得分:1)

我认为问题是,当您在playlistView.render();中致电Router时,playlist.collection仍未填充。

您信任console.log(this.collection);向您展示的内容,但您无法信任console.log()复杂对象。

检查:

答案 1 :(得分:0)

我认为问题与您在将PlayListView返回require.js之前对其进行初始化的事实有关。您也可以在收集完成提取之前随意调用PlaylistView的render方法。

  1. 所以当你通过http://example.com时:
    1. 需要init startView
    2. require init playListView - &gt; collection fetch start
    3. 路线到startView
    4. playListView fetch返回 - &gt;现在已经填充的集合
    5. 点击链接 - &gt;正确渲染playListView
  2. 当您浏览http://example.com/#/playlist时:
    1. 需要init startView
    2. require init playListView - &gt; collection fetch start
    3. 路线到playListView - &gt;渲染playListView不正确,因为集合仍在提取(也就是没有什么可循环)
    4. playListView fetch返回 - &gt;现在已经填充的集合
  3. 更改此行 return new PlaylistView; 对此 return PlaylistView;

    并且Router当然也应该改变

    function ($, _, Backbone, startView, **PlaylistView**) // change the variable name
    ...
    var AppRouter = Backbone.Router.extend({
      ...
      playlistView: null, // Add attribute for the router
      ...
      playlist: function () {
        playlistView = new PlayListView();
        // No render because you bound the render to the reset of the collection !!!
      },
      ...
    }
    ...
    

    现在,您仍然无法初始化您的播放列表视图,同时仍然需要卸载某些内容。

答案 2 :(得分:0)

在MVC模式中,视图响应模型中的更改。您可以在代码中设置:

this.collection.on('reset', this.render, this);

但问题是你没有导致重置,这反过来会导致你的视图重新渲染。因此,不是在'播放列表'中调用render方法,而是将集合的url更改为适当的REST端点,然后执行collection.fetch。完成提取后,将触发“重置”,然后调用渲染,正确反映更新的集合。