在backbone.js中提升和收听模型中的事件

时间:2014-02-18 20:56:02

标签: javascript backbone.js underscore.js backbone-events

我有一个Backbone应用程序,其模型如下所示:

它基本上是一个音乐浏览器应用程序。应用程序加载多个相册,每个相册都有一个与之关联的AlbumMetadata对象。

此外,该专辑有一系列歌曲,每首歌曲都有一个与之关联的SongMetadata对象。

基本上,对象层次结构是这样的:

Albums (Collection)
    |
    |____ Album 1 (Model)
         |
         |____ AlbumMetadata (Model)
         |
         |
         |____ Songs (Collection)
                    |
                    |____ Song 1 (Model)
                    |           |
                    |           |____ SongMetadata (Model)
                    |
                    |____ Song 2 (Model)
                                |
                                |____ SongMetadata (Model)

以下是我的代码:

var MusicBrowser = MusicBrowser || {};

MusicBrowser.SongMetadata = Backbone.Model.extend({
    initialize: function () {
        this.fetch();
    }

});

MusicBrowser.AlbumMetadata = Backbone.Model.extend({
    initialize: function () {
        this.fetch();
    }
});

MusicBrowser.Song = Backbone.Model.extend({
    initialize: function () {
        var songMetadata = new MusicBrowser.SongMetadata({ albumId: this.collection.albumId, songId: this.get("Id") });
        this.set("metadata", songMetadata);
    }
});

MusicBrowser.Songs = Backbone.Collection.extend({
    model: BundleBrowser.Song,
    initialize: function (models, options) {
        this.albumId = options.albumId;
        this.fetch();
    }
});

MusicBrowser.Album = Backbone.Model.extend({

    initialize: function () {
        var songs = new MusicBrowser.Songs([], { albumId: this.get('Id') });
        this.set('songs', songs);

        var albumMetadata = new MusicBrowser.AlbumMetadata({ albumId: this.get('Id') });
        this.set("metadata", albumMetadata);
    }
});

MusicBrowser.Albums = Backbone.Collection.extend({
    model: MusicBrowser.Album,
    initialize: function () {
        this.fetch();
    }
});

我希望能够在更新父级相册模型的AlbumMetadata时自动更新Songs集合中每首歌曲的SongMetadata。我如何通过活动来做到这一点?

如何从AlbumMetadata对象引发事件并从歌曲集合中的SongMetadata模型订阅该事件?

1 个答案:

答案 0 :(得分:0)

你可以这样做:

var MusicBrowser = MusicBrowser || {};

MusicBrowser.SongMetadata = Backbone.Model.extend({
    initialize: function () {
        this.fetch();
    }

});

MusicBrowser.AlbumMetadata = Backbone.Model.extend({
    initialize: function () {
        this.fetch();
    }
});

MusicBrowser.Song = Backbone.Model.extend({
    initialize: function () {
        var songMetadata = new MusicBrowser.SongMetadata({ albumId: this.collection.albumId, songId: this.get("Id") });
        this.set("metadata", songMetadata);

        this.bind('albumMetadata', function(albumMetadata) {
            // here you have the albumMetadata and the songMetadata
        });
    }
});

MusicBrowser.Songs = Backbone.Collection.extend({
    model: BundleBrowser.Song,
    initialize: function (models, options) {
        this.albumId = options.albumId;
        this.fetch();

        this.bind('albumMetadata', function(albumMetadata) { 
            _.each(this.models, function(model) {
                model.trigger('albumMetadata', albumMetadata); 
            });
        });
    }
});

MusicBrowser.Album = Backbone.Model.extend({

    initialize: function () {
        var songs = new MusicBrowser.Songs([], { albumId: this.get('Id') });
        this.set('songs', songs);

        var albumMetadata = new MusicBrowser.AlbumMetadata({ albumId: this.get('Id') });
        this.set("metadata", albumMetadata);
        albumMetadata.bind('change', function() { songs.trigger('albumMetadata', this); }, albumMetadata);
    }
});

MusicBrowser.Albums = Backbone.Collection.extend({
    model: MusicBrowser.Album,
    initialize: function () {
        this.fetch();
    }
});