【问题标题】:Backbone.js views - binding event to element outside of "el"Backbone.js 视图 - 将事件绑定到“el”之外的元素
【发布时间】:2012-01-06 15:18:39
【问题描述】:

this 问题的第二个答案很好地解释了 Backbone.js 视图中的事件声明如何限定为视图的 el 元素。

将事件绑定到el 范围之外的元素似乎是一个合理的用例,例如页面不同部分的按钮。

实现这一目标的最佳方法是什么?

【问题讨论】:

  • 在我看来,视图负责监听其关注的外部事件似乎是不合理的。现在,如果您指的是“全局”类型的视图(比如绘制子视图),那么 Backbone/jQuery 的委托将继续为您所说的这个按钮工作。
  • 我可能误解了一些事情(我使用 Backbone 的第一天)——但作为一个简单的例子,我想象一个列表项的视图(一个包含
      的 div),但是表单添加一个位于该 div 之外的新列表项。
  • @WilliamLannen 如果要处理添加新项目的全局应用程序按钮的事件,请创建一个作为应用程序“容器”的视图,处理这些类型的事件。这就是我使用的方法

标签: javascript backbone.js


【解决方案1】:

没有真正的理由要绑定到视图之外的元素, 还有其他方法。

那个元素很可能在它自己的视图中,(如果不是,考虑给它一个视图!) 既然它在它自己的视图中,你为什么不在那里进行绑定,并在回调函数中, 使用 .trigger(); 触发事件。

subscribe to that event 在当前视图中,并在触发事件时触发正确的代码。

看看 JSFiddle 中的这个例子,http://jsfiddle.net/xsvUJ/2/

这是使用的代码:

var app  = {views: {}};

app.user = Backbone.Model.extend({
    defaults: { name: 'Sander' },
    promptName: function(){
        var newname = prompt("Please may i have your name?:");
        this.set({name: newname});
    }
});

app.views.user = Backbone.View.extend({
    el: '#user',
    initialize: function(){
        _.bindAll(this, "render", "myEventCatcher", "updateName");
        this.model.bind("myEvent", this.myEventCatcher);
        this.model.bind("change:name", this.updateName);
        this.el = $(this.el);
    },
    render: function () {
        $('h1',this.el).html('Welcome,<span class="name">&nbsp;</span>');
        return this;
    },
    updateName: function() {
        var newname = this.model.get('name');
        console.log(this.el, newname);
        $('span.name', this.el).text(newname);
    },
    myEventCatcher: function(e) {
        // event is caught, now do something... lets ask the user for it's name and add it in the view...
        var color = this.el.hasClass('eventHappened') ? 'black' : 'red';
        alert('directly subscribed to a custom event ... changing background color to ' + color);
        this.el.toggleClass('eventHappened');

    }
});

app.views.sidebar = Backbone.View.extend({
    el: '#sidebar',
    events: {
        "click #fireEvent" : "myClickHandler"
    },
    initialize: function(){
        _.bindAll(this, "myClickHandler");
    },
    myClickHandler: function(e) {
        window.user.trigger("myEvent");
        window.user.promptName();
    }
});


$(function(){
    window.user = new app.user({name: "sander houttekier"});
    var userView = new app.views.user({model: window.user}).render();
    var sidebarView = new app.views.sidebar({});
});

【讨论】:

  • 这篇文章中描述的事件聚合器似乎也是一个不错的选择:lostechies.com/derickbailey/2011/07/19/…
  • 是的,虽然我的示例可以工作,但在更大的应用程序中,您可能希望保持事件井井有条,而像 Derick 所说的 eventAggregator 可以很好地做到这一点。但是,由您决定您的应用程序是否需要它,事件都是相同的,您只需将它们绑定到 1 个对象并监听 1 个对象,而不是将它们绑定到模型本身。两者都会很好用:)
  • 我不同意您不需要它:在许多情况下,单击元素外部会禁用视图(对话框、编辑模式)。或者至少......我不同意,除非有更好的方法。
  • 我需要这种行为的一种情况是因为 zurb-foundation 的显示模式将其附加到 html 正文而不是 el。
【解决方案2】:

更新:这个答案不再有效/正确。请参阅下面的其他答案!

你为什么要这样做?

除此之外,您总是可以使用常规的 jQuery 处理程序绑定它。例如

$("#outside-element").click(this.myViewFunction);

IIRC,Backbone.js 只使用常规的 jQuery 处理程序,所以你基本上在做同样的事情,但打破了范围 :)

【讨论】:

  • 接受这一点,因为它直接回答了我的问题——尽管我现在意识到这可能不是一个好主意!!
  • 坏主意,永远不要引用视图之外的元素。而是创建一个外部视图,并将其用作“控制器”
  • 确实,自从我 2 年前的回答以来,我已经了解了很多关于 Backbone 的知识:D
猜你喜欢
  • 1970-01-01
  • 2018-12-12
  • 2012-01-16
  • 1970-01-01
  • 2014-01-07
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多