【问题标题】:Backbone error when creating a second (collection) view创建第二个(集合)视图时出现主干错误
【发布时间】:2014-04-10 12:05:41
【问题描述】:

我正在尝试为我的收藏创​​建第二个视图。

main.js

window.App = {
    Models: {},
    Collections: {},
    Views: {},
    Routers: {},
    init: function () {
        console.log('Hello from Backbone!');
        var book = new this.Models.BookModel({
            title: 'JS is awesome',
            author: 'Douglas Crackford'
        });

        var book2 = new this.Models.BookModel({
            title: 'JS the good parts',
            author: 'Douglas Crackford'
        });

        var bookCollection = new this.Collections.BookCollection;
        bookCollection.add([book, book2]);


        var view = new this.Views.BookView();
        //next line creates error 
        var peopleView = new this.Views.PeopleView();
    }
};

$(document).ready(function () {
    App.init();
});

BookView.js

App.Views = App.Views || {};

(function () {
    App.Views.BookView = Backbone.View.extend({

        el: $('#footer'),

        template: _.template($ ('#books').html()),

        initialize: function () {
            console.log('BookView initialized');
        },

        render: function () {
            this.$el.html(this.template(this.model.toJSON()));
        }

    });
})();

PeopleView.js

App.Views = App.Views || {};

(function () {
    App.Views.PeopleView = Backbone.View.extend({

       tagName: 'ul',

       initialize: function() {
           console.log('peopleView init')
       }

    });
})();

已创建输出

Hello from Backbone!                                main.js:8
BookView initialized                                BookView.js:11
Uncaught TypeError: undefined is not a function     main.js:24

我觉得这个错误很奇怪。如果我将代码从 BookView 复制到 PeopleView 并且只调用这个新的 PeopleView(并编辑 BookView),我会得到同样的错误,而代码看起来是有效的,因为它执行了(参见 console.log)。 我觉得这很奇怪。我错过了什么?

编辑:

添加图片以显示执行顺序。

【问题讨论】:

  • 尝试删除 App.Views = App.Views || {};它不会与 beetwen (function(){...})() 同时执行,+ 它没有用,因为您的 App.js 已经使用 App.Views = {} 进行了初始化
  • 不幸的是,当我删除 App.Views = App.Views || 时没有效果{};
  • 你确定所有的js文件都包含在了html中?

标签: javascript backbone.js yeoman


【解决方案1】:

问题是范围之一。

调用init方法时,是在Window范围内调用的,所以this的值为Window。你可以在你的init方法中console.log(this)查看。

您可以做几件事。当您将App 附加到window 对象时,您可以直接调用它:

  var bookCollection = new App.Collections.BookCollection;

或者你可以将init的调用绑定到App对象:

App.init.call(App);

这会将this 的值绑定到call 的第一个参数。

您可以通过在传递函数 doc ready 方法时直接绑定来进一步简化此操作:

$(document).ready(App.init.bind(App));

More Info On Scopes

【讨论】:

  • 我已经修改过requireJS,但在模板方面遇到了一些问题,将再次研究它。我还添加了执行顺序的图片。顺便说一句,这是一个基本的 yeoman 设置。
  • 对我的回答进行了重大更改。
  • 不用担心。我强烈建议您阅读更多有关范围和闭包的信息,并熟悉 AMD 系统,例如 requirejs
  • 我目前正在重写 requireJS 中的所有内容,并且可以正常工作。我真正喜欢使用 requireJS 是你必须停下来想想你必须在定义部分包含哪个文件。这将迫使您考虑应用程序的每个部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
  • 2012-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多