请帮我找bug

时间:2012-04-16 21:46:02

标签: javascript backbone.js coffeescript

这两张图片的说明 image 1 image 2

代码

showUserProfile: (user_data)->
    console.log "Routers.AppRouter showUserProfile()", user_data
    window.user_profile = user_data

    playlists_both_people = user_profile['playlists']

    my_profile['playlists'].forEach (pl)-> playlists_both_people.push(pl)

    @playlists = new Playlists.Collections.PlaylistsCollection( playlists_both_people )

    $("#app").html( new Playlists.Views.User.ShowView(user_data).render().el )
    @ok()

1 个答案:

答案 0 :(得分:12)

既然每个人都已经击败了你,我会很高兴并告诉你你做错了什么。

您有一个简单的引用问题。首先将user_data对象传递给您的函数。然后你再次引用user_data点在这里:

window.user_profile = user_data

现在您的数据如下所示:

window.user_profile ->-+
                       |
                       +->- {playlists: [ ], ...}
                       |
user_data ----------->-+

然后在此处再次引用user_data.playlists

playlists_both_people = user_profile['playlists']

现在你掌握了这个:

window.user_profile ->-+
                       |
                       +->- {playlists: [ ], ...}
                       |      ^
user_data ----------->-+      |
                              |
playlists_both_people --->----+

然后你将一堆东西推到playlists_both_people数组上,并想知道为什么它也改变了user_data.playlists。该图告诉您原因:您从未复制任何内容,只是通过多个变量引用相同的数据。

你正在使用Backbone所以你有下划线,也许_.clone可以帮助你:

playlists_both_people = _(user_profile['playlists']).clone()

这会在user_profile.playlists中为您提供user_data.playlists(此时与playlists_both_people相同)的(浅)副本,而下一个forEach则不会改变user_data中的任何内容。

请注意,window.user_profile仍可能存在双重引用问题。您不能只使用一个_.clone来解决这个可能的问题,但是您必须单独克隆每个成员,因为_.clone只能执行浅拷贝。但是,你可能有jQuery并且$.extend支持深度复制,因此这可能是一个选项。

我还建议不要将内容直接放在window中。您最好为应用程序设置命名空间,比如window.app,然后使用该命名空间:

window.app.user_profile = ...