在加载主布局之前查看加载

时间:2013-02-13 15:37:28

标签: backbone.js requirejs

这是来自Backbone boilerplate: "this.model is undefined"的后续问题。我能够解决一些结构,但遇到了一个新问题。我正在使用骨干样板,它使用layoutManager适配器来设置视图。主视图以及随后的第一个视图似乎正在正确加载所有资源,尽管后续视图似乎在主视图加载之前触发。这是我的路由器文件:

define([
    // Application.
    "app",

    //Modules
    "modules/homepage"
],
    function (app, Homepage) {
        "use strict";

        // Defining the application router, you can attach sub routers here.
        var Router = Backbone.Router.extend({
            initialize: function(){
                var collections = {
                    homepage: new Homepage.Collection()
                };

                _.extend(this, collections);

                app.useLayout("main-frame").setViews({
                    ".homepage": new Homepage.Views.Index(collections)
                }).render();
            },

            routes:{
                "":"index"
            },

            index: function () {
                this.reset();
            },

            // Shortcut for building a url.
            go: function() {
                return this.navigate(_.toArray(arguments).join("/"), true);
            },

            reset: function() {
                // Reset collections to initial state.
                if (this.homepage) {
                    this.homepage.reset();
                }

                // Reset active model.
                app.active = false;
            }

        });

        return Router;
    }
);

这是我的模块:

define([
    "app",
    ["localStorage"]
],
function(app){
    "use strict";

    var Homepage = app.module();

    Homepage.Model = Backbone.Model.extend({

        defaults: function(){
            return {
                homepage: {}
            };
        }
    });

    Homepage.Collection = Backbone.Collection.extend({
        //localStorage: new Backbone.LocalStorage("Homepage.Collection"),

        refreshFromServer: function() {
            return Backbone.ajaxSync('read', this).done( function(data){
                console.log(data);
                //save the data somehow?
            });
        },

        /*model: Homepage.Model,*/

        cache: true,

        url: '/app/json/test.json',

        initialize: function(options){
            if (options) {
                this.homepage = options.homepage;
            }else{
                //this.refreshFromServer();
            }
        }
    });

    Homepage.Views.Index = Backbone.View.extend({
        template: "homepage",
        el: '#mainContent',

        serialize: function() {
            return {
                collection: this.options.homepage
            };
        },

        initialize: function(){
            this.listenTo(this.options.homepage,{
                "reset": this.render,
                "fetch": function(){
                    $(this.el).html("Loading...");
                }
            });

        }
    });

    return Homepage;
});

如您所见,“主框架”模板是加载到页面中的主模板。我希望之后加载主页模板,将其填充到id“#mainContent”中。但在这种情况下,“#mainContent”尚不存在,因此主页模板不会在任何地方加载。

2 个答案:

答案 0 :(得分:0)

这看起来不对:

define([ // <- first bracket
    "app",
    ["localStorage"] // <- second bracket
],
function(app){
...

它是如何在您的代码中,或一些复制粘贴侥幸?

答案 1 :(得分:0)

经过多方努力,我决定放弃使用骨干 - 样板,现在使用Backbone / RequireJS / localStorage适配器进行以下设置:

<强> app.js:

define([
    'jquery',
    'underscore',
    'backbone',
    'router' // Request router.js
], function($, _, Backbone, Router){
    var initialize = function(){
        Router.initialize();
    };

    return {
        initialize: initialize
    };
});

<强> main.js

require.config({
    paths: {
        jquery: 'libs/jquery',
        underscore: 'libs/underscore',
        backbone: 'libs/backbone',
        'backbone.localStorage': 'libs/backbone.localStorage',
        templates: 'templates'
    },
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscore','jquery'],
            exports: 'Backbone'
        },
        'backbone.localStorage': {
            deps: ['backbone'],
            exports: 'Backbone'
        }
    }
});

require([
    'app'

], function(App){
    App.initialize();
});

<强> router.js

define([
    'jquery',
    'underscore',
    'backbone',

    //Modules
    "modules/homepage"
],
    function ($, _, Backbone, Homepage) {
        "use strict";

        // Defining the application router, you can attach sub routers here.
        var Router = Backbone.Router.extend({
            routes:{
                "":"index"
            }
        });

        var initialize = function(){

            var app_router = new Router;

            app_router.on('route:index', function(){
                // Call render on the module we loaded in via the dependency array
                var collection = new Homepage.Collection();
                var homepage;
                collection.fetch({
                    success: function(){
                        if(collection.length === 0){
                            console.log('refreshing from server...');
                            collection.refreshFromServer({
                                success: function(data){
                                    collection.add(data);
                                    collection.invoke('save');
                                    homepage = new Homepage.Views.Index({
                                        collection: collection
                                    }).render();
                                }
                            })
                        }else{
                            console.log('already loaded in localStorage...');
                            homepage = new Homepage.Views.Index({
                                collection: collection
                            }).render();
                        }
                    }
                });

            });

            Backbone.history.start();
        };
        return {
            initialize: initialize
        };
    }
);

<强> homepage.js:

define([
    "jquery",
    "underscore",
    "backbone",
    "backbone.localStorage",
    "text!templates/homepage.html"
],
function($, _, Backbone, localStorage, homepageTemplate){
    "use strict";

    var Homepage = { Views: {} };

    Homepage.Model = Backbone.Model.extend({

        defaults: function(){
            return {
                homepageData: {}
            };
        }
    });

    Homepage.Collection = Backbone.Collection.extend({
        localStorage: new Backbone.LocalStorage("RGPData"),

        refreshFromServer: function(options) {
            return Backbone.ajaxSync('read', this, options);
        },

        url: 'json/test.json',

        model: Homepage.Model
    });

    Homepage.Views.Index = Backbone.View.extend({
        template:"homepage",
        el: '#mainContent',

        initialize: function(){
            this.listenTo(this.collection, 'change', this.render);
            this.listenTo(this.collection, 'destroy', this.remove);
        },

        render: function(){
            console.log('rendering...');
            $(this.el).html( homepageTemplate, this.collection);
            return this;
        }
    });

    return Homepage;
});

这种方式有效,我让应用程序使用localStorage适配器,而我的集合中有一个“refreshFromServer”,如果localStorage为空,则从JSON文件中读取。在插入视图之前,将在路由器中获取该集合。

我已经花了很长时间才发现一切是如何运作的,所以希望这个答案可以帮助其他任何人比我做得更好。

有几个笔记,我使用text.js来引入模板。

另一个注意事项,我尝试了包括backbone.localStorage并返回只是'Backbone'(如http://kilon.org/blog/2012/08/build-backbone-apps-using-requirejs/所示),但由于某些原因不起作用,我的homepage.js文件一直说“Backbone。模型没有定义“。因此,我最终将两者都纳入了定义。