2

我已经开始使用backbone.js 并且遇到了一个问题。我希望能够通过 onclick 事件显示/隐藏 div(由视图呈现)。问题是事件仅适用于子元素,并且被单击的元素是视图的兄弟/父级。我已经通过在视图“初始化”函数中添加一个处理程序来解决这个问题,但我不认为这是要走的路。我也没有使用“主视图”,否则我怎样才能完成这项工作?

4

1 回答 1

6

如果没有父视图,那么您可以像这样在每个视图之外的视图之间连接事件。

var viewClicked = new ViewClicked();

var viewListening = new ViewListening();

viewListening.listenTo(viewClicked, "clicked:view", viewListening.respondToClick);

您不需要父视图来执行上述操作,即使正如评论所建议的那样,父视图可能是一个好主意。事实上,无论您是否在父视图中连接事件,该方法都是相同的!

因此,您可以通过在初始化函数中处理事件来按照自己的方式进行操作,但这会将一个视图耦合到另一个视图。或者,您可以像上面演示的那样进行操作,这可以防止视图耦合,但需要父视图、某种关闭或污染全局范围。通常最好不要将视图紧密耦合,因为它会减少封装和可能的重用,因此您可以考虑以某种方式采用上述方法。

最后,您可以使用某种中央事件总线(pub sub object),这在这个问题中进行了讨论。这将引入另一个对象,但允许您在视图的初始化函数中处理事件,但耦合不那么紧密(您将耦合到全局或范围事件总线,而不是特定视图)。

当然,您也可以在父视图中使用本地范围的事件总线 :)

更新

如果你只有一个视图并且锚点在视图之外,你可以在锚点上使用标准的 jQuery click 事件来调用视图上的切换函数。重要的是要注意_.bindAll确保切换事件的上下文是视图对象。例如:

HTML

<a href="#" id="showView">click me</a> 

<div id="myView"></div>

JAVASCRIPT

var MyView = Backbone.View.extend({
    initialize: function() {
        // _.bindAll binds functions called by events to the 
        // view (by passing it the view context as 'this'
        _.bindAll(this, "toggle");

        // put some content in the view
        this.$el.append("Now you see me!");
    },

    toggle: function() {
        // jQuery toggle function
        this.$el.toggle();
    }
});

var myView =  new MyView({ el: $("#myView")});

$("#showView").click(myView.toggle);

我为您提供了一个工作小提琴,以便您可以看到它的实际效果。

我提到的关于使用父视图或某种闭包的初始点仍然是一个好主意。真的有理由不这样做吗?

更新 2

使用包含子视图的父视图执行此操作如下:

HTML

<div id="parentView"></div>

JAVASCRIPT

var ShowView = Backbone.View.extend({
    events: {
        "click #showView": "click"
    },

    click: function() {
        this.trigger("showView:click");
    },

    render: function() {
        this.$el.append('<a href="#" id="showView">click me</a>');
        return this;
    }
});

var MyView = Backbone.View.extend({
    initialize: function() {
        // _.bindAll binds functions called by events to the 
        // view (by passing it the view context as 'this'
        _.bindAll(this, "toggle");

        // put some content in the view
    },

    render: function() {
        this.$el.append('Now you see me!');
        return this;
    },

    toggle: function() {
        // jQuery toggle function
        this.$el.toggle();
    }
});

var ParentView = Backbone.View.extend({
    initialize: function() {
        this.showView = new ShowView({ 
            id: "showView"
        });
        this.myView = new MyView({ 
            id: "myView"
        });
        this.listenTo(this.showView, "showView:click", this.myView.toggle)
    },

    render: function() {
        this.$el.append(this.showView.render().$el);
        this.$el.append(this.myView.render().$el);
        return this;
    }

});

var parentView = new ParentView ({el: $("#parentView") });
parentView.render();

这是一个演示它的工作小提琴。您可能认为对于您的问题的上下文而言,使用父视图的方法过于矫枉过正,您可能是对的!然而,随着您的应用程序变得越来越复杂,许多视图嵌套在许多级别上,您会发现父视图方法开始变得更有意义并开始发挥作用。

于 2013-07-04T09:43:54.743 回答