简体   繁体   中英

Access click event outside the el in backbone view

How can i access click event outside the el scope.

What i have : 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>

View :

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();
    }
});

Ive gone through the following :

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

Howto bind a click event in a Backbone subview

but doesn't really help me get it to work.

How can i get the click event of .right_btn inside the view. I cannot change the template structure to include the right_btn inside the el . Is here anyway to bind the outside element or recognize the click event inside a backbone view itself.

Unfortunately, there is no way of doing this using just the backbone library. Backbone expects the view to only handle the events within it's specific DOM element.

It would be best, if possible, to refactor your code so that you do not have to break these conventions. Blurring the boundary of a view can give you difficulty later on if you need to reposition the view and it has dependencies on it's parent environment.

If possible, create a parent view that contains the HTML you have listed above, and use that view to bind to the event and submit the form of it's child view.

If you have no choice but to do things this way, then I would advise using jQuery 'on' to bind to the event.

// 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);

Actually there is a way :

The following is the original view which have a main template and inside the element template_loader, the forgotpassword template is renderer. The button right_btn is outside the elements scope and it did not fire.

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();
    }
});

So after a lot of research, i found a solution to my problem. Im not sure whether this has any drastic problems. I have not encountered anything yet and i will update this post if i find anything :

The idea to create a new instance for the same view, but this time with another el. By this way, we get to execute the initialize and render functions with the first el and use the next one for the events.

One downside is that you will not be able to use something like this to obtain first el peoperties. But since i am using jquery, i can use the selectors to get through this. Other than that, i did not find any issues... yet.!

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

is your right_btn in another view?

you can do this by implementing a global event bus :)

see this answer for more details. Call a function in another Marionette.ItemView

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM