Javascript 主干:视图已与元素失去联系

Javascript 主干:视图已与元素失去联系,javascript,backbone.js,Javascript,Backbone.js,我有一些ViewCollection,它可以渲染所有子视图 define( ['jquery', 'underscore', 'backbone', 'text!templates/main/layout.html', 'text!templates/main/index.html', 'views/security/login', 'views/security/registration'], function($, _, Backbone, LayoutTemplate,

我有一些ViewCollection,它可以渲染所有子视图

define(
    ['jquery', 'underscore', 'backbone', 'text!templates/main/layout.html', 'text!templates/main/index.html', 'views/security/login', 'views/security/registration'], 
    function($, _, Backbone, LayoutTemplate, ContentTemplate, LoginView, RegistrationView) {

    var IndexView = Backbone.View.extend({

        tagName: "div",

        className: "container",

        template: LayoutTemplate,

        render: function() {
            this.$el.html(LayoutTemplate);

            this.$('div.content').html(ContentTemplate);
            this.$('div.sidebar').append(new LoginView().render().el);
            this.$('div.sidebar').append(new RegistrationView().render().el);

            return this;
        }

    });

    return IndexView;

});
这个很好用! 不幸的是,我注意到,例如LoginView不能再处理事件了

define(
    ['jquery', 'underscore', 'backbone', 'text!templates/security/login.html'], 
    function($, _, Backbone, LoginTemplate){

    var LoginView = Backbone.View.extend({

        tagName: "form",

        className: "login well",

        template: LoginTemplate,

        events: {
            "submit form.login": "submit" 
        },

        render: function(){
            this.$el.html(this.template);

            return this;
        },

        submit: function(e){
            e.preventDefault();

            var credentials = {
                'username': $(e.target[1]).val()
                , 'password': $(e.target[2]).val()
            };

            console.log(JSON.stringify(credentials));

            $.ajax({
                url: '/session'
                , type: 'POST'
                , contentType: 'application/json'
                , data: JSON.stringify(credentials)
                , success: function() {
                    window.Router.navigate('node', { trigger: true });
                }
                , error: function(xhr, status, error) {
                    console.log([xhr, status, error]);
                    $(e.target[1]).closest('div.control-group').addClass('error');
                    $(e.target[2]).closest('div.control-group').addClass('error');
                }
            });
        }
    });

    return LoginView;

});
浏览器不发送ajax调用,而是尝试提交编码为GET请求的表单数据url,这表示视图不再侦听任何视图

是否有将视图事件重新绑定到元素的选项?

login.html

<fieldset>
    <legend>login</legend>
    <div class="control-group">
        <label class="control-label" for="_session_username">username:</label>
        <div class="controls">
            <input type="text" id="_session_username" name="session[username]" placeholder="george78" />
        </div>
    </div>
    <div class="control-group">
        <label class="control-label" for="_session_password">password:</label>
        <div class="controls">
            <input type="password" id="_session_password" name="session[password]" placeholder="••••••" />
        </div>
    </div>
    <button type="submit" class="btn btn-primary">login</button>
</fieldset>

登录
用户名:
密码:
登录
表单标记也在视图中定义。login class属性。

我找到了解决方案

我们有一个范围问题。因为我直接在视图中定义了表单(标记名:“表单”),所以最顶层的对象是“form.login”。但我们不能再通过选择器解决这个问题了。我们只能选择子对象。(参见主干内部构件)

之前:

    events: {
        'keyup form.login input': 'checkInput'
        , 'submit form.login': 'submit'
    },
之后:

    events: {
        'keyup input': 'checkInput'
        , 'submit': 'submit'
    },

我不明白为什么提交事件没有被触发。您试过调试一下吗?例如,将
控制台.log
放入
submit
函数中。还要检查css选择器
表单。登录名
实际上是正确的。@fguillen是的,没有console.log,检查了类,整个页面在提交时重新加载,因为e.preventDefault();不会被调用(在事件函数中),因此,这现在有点奇怪。我添加了一个keyup事件,它似乎很有效。只有submit似乎被破坏(与registrationView相同),这意味着必须在视图中明确设置this.el才能工作。。。但这会破坏我的渲染吗?编辑:这里也一样:。事件绑定到el,这就是为什么提交不起作用。但是我如何在渲染中解决这个问题呢?我不是完全正确的:在你的
LoginView中有一个
表单
。$el
,实际上是
LoginView.$el
本身:)