【问题标题】:Access click event outside the el in backbone view在主干视图中访问 el 外的点击事件
【发布时间】:2013-11-25 12:45:19
【问题描述】:

如何访问el 范围之外的点击事件。

我有什么: HTML :

<div class="right_btn"></div>
<div id="template_loader">
    <!-- HTML template goes here which contain form inputs-->
    <input type="text" class="forgot_password_email" name="forgot_password_email"/>
</div>

查看:

var ForgotPasswordView = Backbone.View.extend({
    el: "#template_loader",
    initialize: function () {
        console.log('Forgot Password View Initialized');
    },
    render: function () {
        blockPage();
        var that = this;  

        $.get(App.baseUrl + 'templates/forgot-password-view.html', function (data) {
            template = _.template(data, { });
            that.$el.html(template);
            unblockPage();
        }, 'html'); 
    },
    events:{
        'click .right_btn':'forgotPasswordSubmit', //Doesn't fire as its outside of el
    }, 
    forgotPasswordSubmit: function(e){
        alert($(".forgot_password_email").val());
        e.preventDefault();
    }
});

我经历了以下:

Backbone.js views - binding event to element outside of "el"

Howto bind a click event in a Backbone subview

但并不能真正帮助我让它工作。

如何在视图中获取.right_btn 的点击事件。我无法更改模板结构以在el 中包含right_btn。无论如何都在这里绑定外部元素或识别主干视图本身内的点击事件。

【问题讨论】:

标签: javascript jquery backbone.js backbone-views backbone-events


【解决方案1】:

不幸的是,仅使用主干库是无法做到这一点的。 Backbone 期望视图只处理其特定 DOM 元素内的事件。

如果可能,最好重构您的代码,这样您就不必打破这些约定。如果您需要重新定位视图并且它依赖于其父环境,那么模糊视图的边界会给您带来困难。

如果可能,创建一个包含您上面列出的 HTML 的父视图,并使用该视图绑定到事件并提交其子视图的表单。

如果你别无选择,只能这样做,那么我建议使用 jQuery 'on' 来绑定事件。

// Put this in your view to ensure that it is only bound when the form is
// added to the page. You could substitute 'on' for 'one' if you don't want
// the binding to maintain after the first submission.
var submitForm = function(){
  $('#template_loader form').submit();
};
$('.right_button').on('click', submitForm);

【讨论】:

  • 其实有办法..请看我的回答..我不确定它有什么问题,但它达到了我的目的..
  • 将元素置于视图范围内绝对是比使用 jQuery 将其定位在范围之外更好的解决方案。如果您使用不同的根元素,请确保不要混淆自己。
【解决方案2】:

其实是有办法的:

以下是原始视图,它有一个主模板和元素template_loader,忘记密码模板是渲染器。 right_btn 按钮在元素范围之外,它没有触发。

var ForgotPasswordView = Backbone.View.extend({
    el: "#template_loader",
    initialize: function () {
        console.log('Forgot Password View Initialized');
    },
    render: function () {
        blockPage();
        var that = this;  

        $.get(App.baseUrl + 'templates/forgot-password-view.html', function (data) {
            template = _.template(data, { });
            that.$el.html(template);
            unblockPage();
        }, 'html'); 
    },
    events:{
        'click .right_btn':'forgotPasswordSubmit', //This will fire.
    }, 
    forgotPasswordSubmit: function(e){
        alert($(".forgot_password_email").val());
        e.preventDefault();
    }
});

所以经过大量研究,我找到了解决问题的方法。我不确定这是否有任何严重的问题。我还没有遇到任何事情,如果我发现任何事情,我会更新这篇文章:

为同一个视图创建一个新实例的想法,但这次使用另一个 el。通过这种方式,我们可以使用第一个 el 执行初始化和渲染函数,并将下一个用于事件。

一个缺点是您将无法使用this 之类的东西来获得第一个el 人员。但是因为我使用的是 jquery,所以我可以使用选择器来解决这个问题。除此之外,我没有发现任何问题......但是。!

new ForgotPasswordView ({
   el:'#master_template'
});

【讨论】:

  • 这将更改根元素以将 right_btn 包含在其范围内。这将起作用,但您也可以从原始视图定义中删除 el: '#template_loader',因为您在实例化 ForgotPasswordView 时会覆盖它。
  • 是的,我知道。但我需要它来渲染函数.. :).. 我已经在答案中解释了这一点.. 我不确定是否还有其他问题。范围问题可以通过使用 jquery 选择器来纠正。模型可以在使用前再次声明,这样我就可以使用类似 modelname.save()..
  • 如果你在初始化时设置了el,那么渲染函数会看到#master_template,而不是#template_loader..
  • 很奇怪..但它目前对我来说工作正常..:(.. 生病仔细检查这个..
【解决方案3】:

您的 right_btn 是否在另一个视图中?

你可以通过实现一个全局事件总线来做到这一点:)

查看此答案了解更多详情。 Call a function in another Marionette.ItemView

【讨论】:

  • 然后你可以在 dom 中绑定一个 onclick 事件,或者使用锚点:例如:
  • 嗨..是的,我试图这样做..但它只是给出了 jquery 错误..我找到了另一种方法..可能不是正确的方法,但让它工作.. .
猜你喜欢
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多