Backbone视图继承

6
我正在尝试编写一个针对对象浏览器的Backbone视图,该浏览器旨在在不同的对象类型和略有不同的操作中实现。
我尝试了简单地扩展我的浏览器中的Backbone视图,然后在我的实现中扩展浏览器,但这会使一些属性被共享。这是一个不希望看到的效果,因为数据会随着每次浏览器创建而附加到所有实现中。
有人能够解决这个问题或提供替代方案吗?
以下是一些代码示例,以便更好地了解当前的情况:
    var BrowserView = Backbone.View;

    _.extend(BrowserView.prototype, Backbone.View.prototype, {
        className: 'browser',

        collections: [],

        events: {

        },

        _events:{

        },

            initialize: function () {
            this._initialize();
        },

        render: function () {
            this._render();
        },

        _initialize: function () {
            this.container = $( this.make('div', {class: 'container'} ) );

            this.$el.append(this.container);

            if ( this.options.collections ) {
                this.collections = [];

                _.each(this.options.collections, this.add, this);
            }

            _.extend(this.events, this._events);

            this.delegateEvents();
        },

        _render: function () {
            this.container.empty();

            _.each(this.collections, function (view) {
                this.container.append(view.el);

                view.render();
            }, this);
        }
    });

    BrowserView.extend = Backbone.View.extend;

    var ContactBrowserView = BrowserView.extend({

    });

编辑 我的问题是子类共享了collections属性。以下是我自己的解决方案,通过继承的方法初始化collections属性。jsfiddle.net/JhZXh/3

4个回答

11

我想我已经找到了解决自己问题的答案。

我相信实现我所寻求的正确方式是将属性的初始化移动到 Backbone 视图提供的 initialize 方法中。这样它们就会被初始化。

var BrowserView = Backbone.View.extend({
    initialize: function () {
        this.collections = [];
    }
});

var FileBrowserView = BrowserView.extend({
    initialize: function () {
        BrowserView.prototype.initialize.apply(this);
        
        this.collections.push({name: 'Example Collection' + Math.rand()});
    }
});


var FileBrowserInstance1 = new FileBrowserView;
console.log(FileBrowserInstance1.collections);

var FileBrowserInstance2 = new FileBrowserView;
console.log(FileBrowserInstance2.collections);

http://jsfiddle.net/yssAT/2/


4

很难看出你的确切目标是什么。

但我这样看 如果您有一个视图对象

var myView = Backbone.View.extend({
    foo: "bar"
});

如果您让它扩展backbone.View......那么您实际上就拥有了一个新的视图对象,其中包含了backbone.view的所有内容以及您作为参数提供的额外选项。

如果您随后创建第二个视图,扩展您的第一个视图,它将获得您的第一个视图中的所有内容,加上它自己的额外内容。

var mySecondView = myView.extend({
    foobar: "f00b@r"
});

如果您创建第二个视图的实例并记录其 foo 属性,它仍将保持值为 "bar"

var mySecondViewInstance = new mySecondView();
console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo);
console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar);

如果我创建一个新的第一个视图实例,并将 foo 改为 "changed-foo",那么在 mySecondViewInstance 上记录的 foo 仍将是 "bar"

var myViewInstance = new myView();
myViewInstance.foo = "changed-foo";
console.log("mySecondViewInstance.foo: ", mySecondViewInstance.foo);
console.log("mySecondViewInstance.foobar: ", mySecondViewInstance.foobar);

一个可以用来玩耍的JS Fiddle在这里: http://jsfiddle.net/saelfaer/uNBSW/


嗨,桑德尔,抱歉我的问题描述不够清楚。我还创建了一个JS-Fiddle来更好地演示我的问题的核心。也许我一开始就应该这样做。我的问题是子类共享集合属性。http://jsfiddle.net/JhZXh/3/ - Eli
无论如何,只需将那个 JSFiddle 和描述添加到您的原始帖子中,不是每个人都会在这里找到它。我会查看它,看看是否能提供更好的适当回答。 - Sander

3

Backbone.View继承不起作用,或者相当复杂。

您应该创建一个通用的对象,并使您的每个视图都从中继承,例如:

var ViewInterface = {
  events        : { /* ... */ },
  initialize    : function (options) { /* ... */ },
  otherFunction : function (options) { /* ... */ },
}

每个视图都将从此对象扩展:
var BrowserView = Backbone.View.extend(_.extend(ViewInterface, {
  anotherFunction : function (options) { /* ... */ },
})

var AnotherView = Backbone.View.extend(_.extend(ViewInterface, {
  yetAnotherFunction : function (options) { /* ... */ },
})

这样做是可行的,但据我所知并不是 OP 需要的。他的问题是,他定义了一个集合属性,而不是 otherFunction。通过从那个视图扩展,两个视图共享对集合的引用,而不是拥有自己的集合。这就是为什么他现在建议自己从初始化方法中初始化它,而不是在视图本身上定义它的原因。 - Sander
2
这并不起作用,因为extend将复制到ViewInterface中,因此AnotherView中也将存在anotherFunction。 - pedroteixeira

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接