骨干 - 当用户通过特定帖子访问网站时,如何管理集合初始化

Backbone - How to manage collection initialization when users access website through specific post?

本文关键字:何管理 初始化 集合 管理 网站 访问 用户 骨干      更新时间:2023-09-26

我正在尝试使用Javascript,Requirejs和Backbonejs创建一个Wordpress主题。整个主题基于每条路线之间的幻灯片切换。

主页显示一个 wallView,其中包含相册集合的每个元素的 albumCoverView。当用户单击专辑封面视图时,他会导航到相应的帖子 URL(触发专辑路由),并在 wallView 和专辑视图之间滑动过渡开始。

这是我的路由器.js文件的代码

define( function( require, exports, module ) {
"use strict";
var app     = require( 'app' );
var cache   = require( 'backbone-cache' );
var Albums  = require( 'modules/albums/index' );
var Wall    = require( 'modules/wall/index' );
var Router = Backbone.Router.extend( {
    routes: {
        ''                          : 'index',
        ':year/:month/:day/:slug/'  : 'album'
    },
    index: function() {
        if( typeof app.albumsCollection == "undefined" ) {
            app.albumsCollection = new Albums.Collection();
            app.albumsCollection.fetch( {
                cache: true,
                success: function() {
                    app.wallView = new Wall.View( {
                        collection: app.albumsCollection
                    } );
                    app.wallView.render();
                    app.wallView.show();
                },
                error: function() {
                    console.log( "Collection: modules/albums -> fetch failed" );
                }
            } );
        }
        else app.wallView.show();
    },
    album: function( year, month, day, slug ) {
        var albumModel = app.albumsCollection.findWhere( { post_name: slug } );
        if( albumModel.get( 'format' ) == "gallery" ) {
            app.albumView = new Albums.Views.Gallery( {
                id      : "album-" + albumModel.get( 'ID' ),
                model   : albumModel
            } );
        }
        else if( albumModel.get( 'format' ) == "image" ) {
            app.albumView = new Albums.Views.Image( {
                id      : "album-" + albumModel.get( 'ID' ),
                model   : albumModel
            } );
        }
        app.albumView.render();
        app.albumView.show();
    }
} );
module.exports = Router;

} );

在这里,我的模块/专辑/集合.js文件的代码

define( function( require, exports, module ) {
"use strict";
var app         = require( 'app' );
var AlbumsModel = require( './model' );
var AlbumsCollection = Backbone.Collection.extend( {
    model   : AlbumsModel,
    url     : app.jsonApi + "albums/get_albums/",
    parse: function( response ) {
        return response.posts;
    }
} );
module.exports = AlbumsCollection;

} );

幻灯片切换由将显示的视图的 .show() 函数管理。

我的问题 :

当用户在主页上时,我正在获取WordPress帖子(使用JSON API插件)并在localStorage中缓存它们(使用主干获取缓存)。

使用这种方法,问题是:当用户通过指向特定帖子的链接访问网站时,专辑集合是未定义的,因此,应用程序找不到相应的专辑数据(var albumModel = app.albumsCollection.findWhere( { post_name: slug } );)。所以,我想知道如何解决这个问题?

  • 我需要使用此方法引导相册集合吗:加载自举模型?
  • 我是否需要在路由器初始化时获取专辑集合并使用 $.when(...)。然后(...在每条路线中 ?
  • 我是否需要在我的 json 控制器中创建一个 get_album 方法来仅获取一个相册,然后在用户转到主页时重置相册集合以重新填充?

欢迎任何建议。

在过去的几个月里,我一直在开发一个大型的javascript应用程序,而您遇到了一个常见问题。

我的解决方案非常简单:每当您需要共享集合/模型时,请检查它是否已加载,如果未加载则获取它。并且,在确保它已加载后,继续执行您想用它执行的任何操作。

若要保留共享模型/集合,请创建stores,以便在需要时保留这些对象。在这种情况下,我的store是我的"静态"_instance变量。

如果内存泄漏与您有关,我建议您在stores对每个对象使用计数,以便您可以获得零计数模型/集合。

例如:

var AlbumsCollection = Backbone.Collection.extend( {
    model   : AlbumsModel,
    url     : app.jsonApi + "albums/get_albums/",
    initialize: function ( options ) {
        this.loaded = false;
        this.listenToOnce('sync', this.onLoaded);
    },
    onLoaded: function () {
        if (!this.loaded) {
             this.loaded = true;
             this.trigger('loaded', this);
        }
    },   
    parse: function( response ) {
        return response.posts;
    }
 },
 // Static part
 {
     _instance: null,
     getInstance: function () {
         if (!this._instance)
              this._instance = new AlbumsCollection();
         return this._instance;
     }    
});

因此,在您的路由器/视图中:

function ... () {
     var collection = AlbumsCollection.getInstance();
      if (collection.loaded)
          this.onAlbumsLoaded(collection);
      else {
          this.listenToOnce('loaded', this.onAlbumsLoaded);
          collection.fetch();
     }
} 

您只需在onAlbumsLoaded函数中执行与集合有关的操作即可。

希望我有所帮助。