如何扩展骨干视图

时间:2012-10-07 12:14:13

标签: javascript backbone.js requirejs

我是SPA的骨干新手,我正在尝试使用backbone和requireJs来开发一个小应用程序。

我遇到的问题是我无法通过传递集合来扩展视图。

嗯,这是名为 MenuView.js

的视图
define([
'Backbone'
], function (Backbone) {
var MenuView = Backbone.View.extend({
    tagName: 'ul',
    render: function () {
        _(this.collection).each(function (item) {
            this.$el.append(new MenuListView({ model: item }).render().el);
        }, this);
        return this;
    }
});
return new MenuView;
});

这是出现错误的 router.js

define([
    'Underscore',
    'Backbone',
    'views/menu/menuView',
    'views/createNew/createNew',
    'collections/menu/menuCollection',
], function (_, Backbone, MenuView, CreateNewView,Menucollection) {

var AppRouter = Backbone.Router.extend({
    routes: {
        'index': 'index',
        'action/:Create': 'Create'
    },
    index: function () {
        CreateNewView.clear();
        //-----------  HERE IS THE PROBLEM ------------
        $('#menu').html(MenuView({ collection: Menucollection.models }).render().el);
    },
    Create: function () {
        CreateNewView.render();
    }
});

var initialize = function () {
    var appRouter = new AppRouter();
    Backbone.history.start();
    appRouter.navigate('index', { trigger: true });
};

return {
    initialize: initialize
};
});

错误消息是“对象不是函数”。我同意这一点,因为MenuView不是一个功能。我试图扩展MenuView(MenuView.extend({collection:Menucollection.models})),错误信息是“objet [object,object]没有方法扩展”。

我认为我试图这样做的方式远离正确的方法。

有人可以建议怎么做吗?

由于

2 个答案:

答案 0 :(得分:1)

@Matti John的解决方案可行,但它更像是一种解决方法,而不是最佳实践恕我直言。

实际上,您只是通过要求它来初始化您的视图,其中:

  1. 限制您永远不接受参数
  2. 点击表现
  3. 如果您在构建实例时继续分配属性,则很难进行单元测试。
  4. 模块应返回“类”视图,而不是该视图上的实例。

    MenuView.js 中,我会将return new MenuView替换为return MenuView;,并在 router.js 中需要时将其归结为ititalzie。

答案 1 :(得分:0)

您的MenuView.js会返回一个初始化的MenuView,您可以这样做:

MenuView.collection = Menucollection

注意我没有选择模型 - 我认为如果不使用模型作为视图集合的替代品会更好,因为阅读代码并且没有Backbone集合作为视图的混淆会很困惑采集。您还将丢失集合中包含的方法(例如,获取/更新)。

如果你这样做,那么你需要更新你的循环(每个循环都可用作集合的方法):

this.collection.each(function (item) {
            this.$el.append(new MenuListView({ model: item }).render().el);
        }, this);