呈现视图 returns 未定义

Rendering the view returns undefined

我有一个 collection 视图,其中包含两个过滤方法和一个带有参数的渲染方法。我遇到的问题是,第一次渲染视图时 returns 我出错了。这是我的 collection:

var ResumeCollection = Backbone.Collection.extend({
    url: 'http://localhost:3000',
    filterActive: function () {
        var active = this.where({interviewed: false});
        return new ResumeCollection(active);
    },
    filterInterviewed: function () {
        var interviewed = this.where({interviewed: true});
        return new ResumeCollection(interviewed);
    }
});

我的观点:

var ResumeList = Backbone.View.extend({
    events { // hash array of filter events },
    initialize: function () {
        this.collection.fetch();
    },

    render: function (filtered) {
        var self = this;
        var data;

        if (!filtered) {
            data = this.collection.toArray(); 
        } else {
            data = filtered.toArray();
        }

        _.each(data, function (cv) {
            self.$el.append((new ResumeView({model: cv})).render().$el);
        });

        return this;
    },

    showActive: function (ev) {
        var filtered = this.collection.filterActive();
        this.render(filtered);
    },

    showInterviewed: function (ev) {
        var filtered = this.collection.filterInterviewed();
        this.render(filtered);
    },

    showAll: function (ev) {
        this.render(this.collection);
    }
});

此视图是通过传递 collection:

在我的路由器中首次呈现的
var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'home'
    },

    initialize: function () {
        this.layout = new LayoutView();
    }

    home: function () {
        this.layout.render(new ResumeList({
            collection: new ResumeCollection()
        }));
    }
});

这是呈现所有其他视图的布局视图:

var LayoutView = Backbone.View.extend({
    el: $('#outlet'),
    render: function (view) {
        if (this.child && this.child !== view) {
            this.child.undelegateEvents();
        }

        this.child = view;
        this.child.setElement(this.$el).render();
        return this;
    }
}); 

当我刚刷新我的页面时,出现 filtered.toArray is not a function 错误并且没有分别呈现任何内容。检查调试器中的所有内容后,我发现第一次呈现视图时,filtered 属性收到一个空的 collection,将其分配给 data 变量,它变成了一个空数组并转到 render 函数的主体,之后变为 undefined。谜团就在这里:每当我单击绑定到我的 show* 事件的项目时,它们的行为完全符合预期并呈现 interviewed === falsetrue 或整个 [=38] 的模型=].这对我来说看起来有点神奇,我完全不知道我能用它做什么。

已添加GitHub repo with this project

您在 AppRouter 上的 home 函数有错字。你多了一个分号。

home: function () {
    this.layout.render(new ResumeList({
        collection: new ResumeCollection();
    }));
}

应该是

home: function () {
    this.layout.render(new ResumeList({
        collection: new ResumeCollection()
    }));
}

我需要删除它才能让 JSFiddle 正常工作:https://jsfiddle.net/4gyne5ev/1/

我建议在您的 IDE 或构建过程 (http://eslint.org/)

中添加某种 linting 工具

您需要像这样将主页 url 内容添加到您的 db.json 文件

"" : [
    {
       'somthing': 'somthing'
    }
]

经过导师的建议,我意识到问题的核心在于 fetch 方法的异步起源——当我在初始化函数中传递 this.collection.fetch 时,它在之后执行我的 render 方法,而不是在它之前,所以当第一次调用视图时,我的 render 方法没有任何东西可以呈现。因此,此修复有效:

var ResumeList = Backbone.View.extend({
    initialize: function (options) {
         this.collection = options.collection();
         // removed .fetch() method from here
    },
    render: function (filtered) {
        var self = this;
        var data;
        // and added it here:
        this.collection.fetch({
            success: function (collection) {
                if (!filtered) {
                    data = collection.toArray();
                } else {
                    data = filtered.toArray();
                }
                self.$el.html(self.template(collection.toJSON()));
                _.each(data, function (cv) {
                   self.$el.append((new ResumeView({model: cv})).render().$el);
               })
            }
        });
    }
});

这完全符合我的需要。