1

这是来自Backbone 样板的后续问题:“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;
});

如您所见,“main-frame”模板是加载到页面中的主模板。我希望稍后加载主页模板,该模板将填充到 ID“#mainContent”中。但在这种情况下,“#mainContent”还不存在,因此主页模板不会加载到任何地方。

4

2 回答 2

0

这看起来不对:

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

是它在你的代码中的样子,还是一些复制粘贴的侥幸?

于 2013-02-14T07:52:01.793 回答
0

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

应用程序.js:

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

    return {
        initialize: initialize
    };
});

主.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();
});

路由器.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
        };
    }
);

主页.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 适配器,同时如果 localStorage 为空,我的集合中有一个“refreshFromServer”可以从 JSON 文件中读取。集合在路由器中获取,然后插入到视图中。

我花了相当长的时间来发现一切是如何运作的,所以希望这个答案能帮助其他人比我更好地站稳脚跟。

几个注意事项,我使用 text.js 来引入模板。

另一个注意事项,我尝试包括backbone.localStorage并返回为'Backbone'(如http://kilon.org/blog/2012/08/build-backbone-apps-using-requirejs/中所述),但出于某种原因那没有用,我的 homepage.js 文件一直说“Backbone.Model 未定义”。因此,我最终将两者都包含在定义中。

于 2013-02-15T18:41:54.883 回答