【问题标题】:Why Backbone.js isn't binding my event为什么 Backbone.js 没有绑定我的事件
【发布时间】:2012-03-20 22:57:02
【问题描述】:

我有一个这样的路由器,作为主要入口点:

window.AppRouter = Backbone.Router.extend({
    routes: {
        '': 'login'
    },
    login: function(){

        userLoginView = new UserLoginView();
    }
});

var appRouter = new AppRouter;
Backbone.history.start({pushState: true});

我有一个这样的模型/集合/视图:

window.User = Backbone.Model.extend({});

window.Users = Backbone.Collection.extend({
    model: User
});

window.UserLoginView = Backbone.View.extend({

    events: {
        'click #login-button': 'loginAction'
    },

    initialize: function(){
        _.bindAll(this, 'render', 'loginAction');
    },

    loginAction: function(){
        var uid = $("#login-username").val();
        var pwd = $("#login-password").val();

        var user = new User({uid:uid, pwd:pwd});
    }
});

我的 HTML 正文如下所示:

<form action="#" method="POST" id="login-form">
    <p>
        <label for="login-username">username</label>
        <input type="text" id="login-username" autofocus />
    </p>
    <p>
        <label for="login-password">password</label>
        <input type="password" id="login-password" />
    </p>
    <a id="login-button" href="#">Inloggen</a>
</form>

注意: HTML 来自使用 express.js 的 Node.js,我是否应该在某处等待文档就绪事件?

编辑:

我试过这个,准备好后创建视图,没有解决问题。

    $(function(){
        userLoginView = new UserLoginView();
    });

【问题讨论】:

  • 我想你可能会回答你自己的问题。看看这个例子documentcloud.github.com/backbone/examples/todos/index.html他们使用“$(function() {”这是准备好的文档。
  • 好的,我也试过这个,但是我将代码的哪一部分包装在准备好的里面。包裹路由器并不能解决问题,包裹模型/集合/视图也没有效果。
  • 虽然它没有回答您的问题,但请考虑绑定到表单上的提交事件('submit #login-form')而不是链接上的点击事件,并将链接更改为输入 type="submit"。除了单击按钮之外,这还允许通过键盘提交表单。您根本不需要更改 loginAction。
  • 使用回车键会很棒。会这样做。

标签: javascript events backbone.js


【解决方案1】:

从您发布的代码来看,它不像您将 el 属性分配给 UserLoginView 实例。我不认为events 哈希将用于绑定事件处理程序,除非视图具有el(即视图的根DOM 元素-see docs)。当您初始化视图时,它将处理程序绑定到根元素,对子元素使用.delegate(),因此没有根元素,没有处理程序,即使使用基于 id 的选择器。试试这个:

window.UserLoginView = Backbone.View.extend({
    el: '#login-form',
    // etc
});

请注意,正如 cmets 中所讨论的,您应该在 DOM 准备好之后执行此操作。这里的标准方法是在$(document).ready 中启动路由器和历史机制:

$(function() {
    var appRouter = new AppRouter;
    Backbone.history.start({pushState: true});
});

【讨论】:

  • 我想我已经尝试过了,但我会再做一次。我认为默认情况下它只会将其绑定到正文。我见过一些没有给出el 属性的例子。
  • 哎呀,解决了。多么愚蠢的错误,我想我应该更好地查看这些示例。
  • 但不必指定。如果省略,它将默认为 div。
  • 如果您创建一个视图并渲染它,如果您不手动为其分配一个 el,它将默认渲染一个 div,如果您渲染一些元素,那么它们将自动绑定到 div 根元素。
  • @PhillipKregg 和 @Jack - 是的,如果未指定任何内容,它将为 el 属性创建默认 DOM 元素。是的,然后您可以使用将正确处理其事件的新元素填充 el。但是您不能使用events 将事件绑定到现有 DOM 元素,而不指定el,它是您尝试绑定到的元素的父元素。
猜你喜欢
  • 1970-01-01
  • 2011-05-05
  • 2012-01-14
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2018-07-21
相关资源
最近更新 更多