主干视图继承

Backbone View Inheritance

本文关键字:继承 视图      更新时间:2023-09-26

我正试图为一个对象浏览器编写一个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

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

我相信实现我想要的目标的正确方法是将属性的初始化转移到Backbone视图提供的初始化方法中。通过这种方式初始化

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/

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

但我就是这么看的如果你有一个视图对象

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

你让它伸展脊梁。看法然后,您实际上有了一个新的视图对象,其中包含backline.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"foomySecondViewInstance上的日志仍将是"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/

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) { /* ... */ },
})

这个要点显示了一个更好的替代方案:https://gist.github.com/2287018