主干点击事件未在模板视图中触发 [英] Backbone click event not firing in template View

查看:18
本文介绍了主干点击事件未在模板视图中触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个基于动态模板的 Backbone 应用程序.我有一个标题视图、一个侧面板视图和页脚视图,它们在调用任何其他视图时动态初始化.问题是我在每个模板视图上都有未触发的事件.例如,我有一个按钮可以更改标题视图中的语言,但它的事件没有触发.

I am working on a Backbone application which is based on a dynamic template . I have a header view, a side panel view and footer view that are dynamically initialized when calling any other view . The problem is I have events on each template view that are not firing. For example i have a button that changes the language in the header view but its event isn't firing.

我的标题视图:

define([ "jquery", "backbone", "text!../../pages/header.html" ], function($,
        Backbone, headerTpl) {

    var header = Backbone.View.extend({
        events : {
            "click #enBtn":"swichToEnglish",
             "click #frBtn":"swichToFrench"
        },
        initialize : function(options) {
             _.bindAll(this, "swichToFrench","swichToEnglish");

            this.render(options.parent);
            //$("#enBtn").css("pointer-events","none");

        },
        render : function(parent) {
            this.template = _.template(headerTpl);
            $(parent).append(this.template);
            return this;
        },
        swichToFrench:function(){
            console.log("switch to frensh");
            if(i18n.currentLocal == 'en'){
                i18n.currentLocal='fr';
                $("#frBtn").css("pointer-events","auto");
                this.render(options.parent);
        }
        },
        swichToEnglish:function(){
            console.log("switch to English");
            if(i18n.currentLocal == 'fr'){
                i18n.currentLocal='en';
                $("#enBtn").css("pointer-events","auto");
                $("#frBtn").css("pointer-events","none");
                this.render(options.parent);
        }   
        }
    });

    return header;
});

在路由器中调用头部视图:

The header view is called in the router :

self._header = new Header({parent: $(".main_container")});

任何解决此问题的方法.我需要知道如何触发这些事件,谢谢.

Any ideas how to fix this issue. I need to know haw to fire these events Thank You.

推荐答案

您的事件处理程序未触发的原因是因为事件处理程序已委托给 views 元素,但您将模板附加到其他一些元素.由于目标元素在这个模板中,没有附加到视图的 el,事件永远不会冒泡到委托给它的处理程序中.

The reason your event handlers is not firing is because the event handlers are delegated to the views element, but you're appending the template to some other element. Since the target elements are in this template which is not appended the view's el, the events will never bubble into the handlers delegated to it.

除此之外,正如@mu 指出的那样,当您执行 $(parent).append(this.template); 时,this.template 是模板函数.您实际上应该使用数据调用它以获取模板.并且您不应该使用像 $('') 这样的全局选择器,而是使用 this.$el.find('') 作为最佳实践.

Apart from that, as @mu is too short pointed out, when you do $(parent).append(this.template);, this.template is the template function. You should actually call it with the data to get the template. and you shouldn't be using global selectors like $('') and use this.$el.find('') instead as best practice.

此外,options 仅在 initialize 方法内部可用,在外部 undefined 可用.

also, options is only available inside the initialize method, and is undefined outside.

不要将父级传递到视图中,然后将其自身附加到父级,而是在视图之外执行此操作并使视图独立.

Instead of passing the parent into the view and then have it append itself to parent, do that outside the view and make the view independent.

还要在视图中声明 template 属性而不是添加它在创建之后作为最佳实践.

Also declare the template property in the view rather than adding it after the creation as a best practice.

并且不需要手动将事件处理程序的上下文绑定到视图,默认情况下,事件处理程序的上下文将是视图.

And there's no need to bind the context of event handlers to the view manually, by default the context of event handler will be the view.

您的视图应如下所示:

define([ "jquery", "backbone", "text!../../pages/header.html" ], function($,
    Backbone, headerTpl) {

  var header = Backbone.View.extend({
    initialize : function(options) {
        this.render();
    },
    template: _.template(headerTpl),
    events : {
        "click #enBtn":"swichToEnglish",
        "click #frBtn":"swichToFrench"
    },
    render : function() {
        this.$el.append(this.template(/* pass the data here*/));
     //--------^----- this is required for the events to work
        return this;
    },
    swichToFrench:function(){
        if(i18n.currentLocal == 'en'){
            i18n.currentLocal='fr';
            this.$el.find("#frBtn").css("pointer-events","auto");
            this.render();
        }
    },
    swichToEnglish:function(){
        if(i18n.currentLocal == 'fr'){
          i18n.currentLocal='en';
          this.$el.find("#enBtn").css("pointer-events","auto");
          this.$el.find("#frBtn").css("pointer-events","none");
          this.render();
      }   
    }
  });

  return header;
});

您可以像这样创建:

self._header = new Header();
$(".main_container").append(self._header.el);

<小时>

看起来您只是希望将视图内容添加到 '.main_container' 中,而不需要其他元素.在这种情况下,您可以使您的视图 el 指向它,而不是通过在以下选项中将其作为 el 传递来创建新元素:


it looks like you just want the view content to be added to '.main_container', and doesn't need another element. In that case you can make your views el point to it rather than creating a new element by passing it as el in the options like:

self._header = new Header({
 el: '.main_container' // this.el will refer to `.main_container` in view
});

那你就不用$(".main_container").append(self._header.el);

如果您出于某种原因必须将父级作为选项传递到视图中,那么您应该将其缓存在 initialize 内的视图中,以便您可以在其他地方引用它.

if you must pass the parent into view as an options for some reason, then you should cache it in the view inside initialize so that you can refer it elsewhere like.

this.parent = options.parent

<小时>

附注:

如您所见,我更改了您声明视图属性的顺序 - initialize 在顶部,然后是模板、事件和渲染.

As you can see, I've changed the order in which you had declared the view's properties - initialize on top followed by template, event and render.

我们初始化视图,创建模板函数,声明要委托的事件,然后渲染视图.

We initialize the view, we create the templating function, we declare the events to be delegated, and then we render the view.

您定义属性的顺序在内部并不重要,但是当其他开发人员查看您的代码时,理解起来要容易得多.但这是一个见仁见智的问题.

The order in which you define properties doesn't matter internally, but when another developer looks at your code, it's much easier to digest. But it's a matter of opinion.

这篇关于主干点击事件未在模板视图中触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆