Backbone.js继承视图

3
我有一个FormView,处理保存和取消等事件。我还有一个AjaxFormView,处理通过ajax保存、取消和获取表单。我有一个AssetFormView,处理保存、取消、通过ajax获取、删除和打印等操作。等等。这里有相当多的重复。
我发现了一篇文章http://kalimotxocoding.blogspot.com/2011/03/playing-with-backbonejs-views.html,其中展示了如何扩展视图。然而,我发现当页面上有多个版本的视图时,属性会互相污染。在backbone中没有内置的安全继承视图的方法吗?
谢谢,
Raif
*嗯,这些东西相当复杂,我当前的交叉污染问题可能是(很可能是)我的错误导致的,但问题仍然存在,那就是在backbone中没有安全继承视图的内置方法吗?

你需要更具体地描述你的问题,才能得到有用的答案:展示一些代码,说明你的期望和问题所在。Backbone 的 extend 函数是主要的继承机制,正如你链接的文章所演示的那样 - 有什么问题吗? - nrabinowitz
是的,通常情况下我会变得非常沮丧,最终向stackoverflow发出问题,只发现要么是我犯了错误,要么是我在几分钟后找到了解决方案。由于我无法撤回问题,希望这将作为指向该主题上好文章的指针。 - Raif
2个回答

2

当你说你的属性在跨类中相互影响时,我希望能了解你的意思。

View.extend 机制运行良好。但请注意,您正在用新函数扩展一个原型。在原型继承中,原型与新实例共享它的对象。

我猜测当你说你的属性是“相互影响”时,实际上你是在做这样一件事:

var baseModel = Backbone.Model.extend({
    defaults: {
        foo: { bar: "baz" }
    }
});

由于对象是共享的,每个baseModel实例最终都会拥有相同的foo对象,给人一种交叉污染的感觉。

如果您将默认值定义为函数,则每个实例将获得自己的foo对象副本,从而消除了交叉污染。

var baseModel = Backbone.Model.extend({
    defaults: function() { return {
        foo: { bar: "baz" }
    } }
});

当然,没有代码,我们无法确定您的问题是什么。只要知道这种机制在社区中被广泛使用而没有出现问题。它是安全的。你只需要理解正在发生的事情。


好的,你的意思是如果我这样做 Backbone.Model.extend({ myProperty: "hello" }) 那么myProperty本质上将是一个静态属性,如果我这样定义它 Backbone.Model.extend({ myProperty: function(){ "hello" } }) 它将成为一个实例属性,并且每个实例都是唯一的?如果是这样的话,那就解释了很多问题。我想我必须将所有属性都作为函数访问,但这是理解正在发生的事情所付出的小代价。非常感谢您提供这些信息并确认这些事实,如果您看到这条消息,请回复。 - Raif
嗯,这似乎不太起作用。我的目标是在每个实例上放置对象集合,以跟踪我在父视图内创建的子视图。发生的情况是,我得到了对象,但当我在对象上设置属性时,它并没有“粘住”。这可能不是一个很好的模式,但我现在想能够做到这一点。我会尝试一些方法,如果我解决了问题,我会回报的。 - Raif
我发布了一个新主题,展示了我正在做的事情,并询问是否疯了。http://stackoverflow.com/questions/7838926/does-this-seem-like-the-best-proper-way-to-do-backbone-js-view-inheritance - Raif
不,函数与属性的交换仅适用于模型的“defaults”属性。 Backbone只是检查它是否为函数并调用它,否则直接使用数据。请参见:http://documentcloud.github.com/backbone/docs/backbone.html#section-18 - Brian Genisio
哇,这是一份非常好的文档!我已经在阅读代码和跟踪它了,但这样做容易多了!感谢您分享了那个链接!根据情况,我实际上正在使用视图而不是模型,所以我基本上做了同样的事情(虽然他们做得更优雅,我可能会效仿)。请查看上面评论中的链接。再次感谢! - Raif

0

我不确定你遇到的是否是同样的问题,但我想在父类中定义一些事件,然后让子类在不覆盖它的情况下扩展属性。

如果我像这样做,我就会覆盖父类定义的内容:

App.parent = Backbone.View.extend({
    events: {
        'click #button-add': 'onAddButtonClicked'
        'click #button-delete': 'onDeleteButtonClicked'
    }

    onAddButtonClicked: function() {
        console.log('onAddButtonClicked');
    },

    onDeleteButtonClicked: function() {
        console.log('onDeleteButtonClicked');
    }
});

App.child = App.parent.extend({
    initialize: function() {
        // This looks redundant but it seems to protect App.parent::events
        this.events = _.extend({}, this.additionalEvents, this.events);

        // THIS IS WRONG and results in errors when I have multiple childdren:
        _.extend(this.events, this.additionalEvents); // <-- this seems to change the parent
    }

    additionalEvents: {
        'click #button-additional': 'onOtherButtonClicked'
    },

    onOtherButtonClicked: function() {
        console.log('child:onOtherButtonClicked');
    }
});

当像这样扩展父级的事件时:

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

我会收到"未捕获的错误:方法'onOtherButtonClicked'不存在",因为我正在修改App.parent的事件字段。 App.child2会崩溃,因为它无法看到由App.child放置在那里的事件。

通过将其更改为:

this.events = _.extend({}, this.additionalEvents, this.events);

我成功保护了父级元素。


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