Alex Dambrouski
Alex Dambrouski

Reputation: 3

When on enter keypress is triggered by jquery my model is undefined

I'm using require.js with backbone.js to structure my app. In one of my views:

    define(['backbone', 'models/message', 'text!templates/message-send.html'], function (Backbone, Message, messageSendTemplate) {
    var MessageSendView = Backbone.View.extend({
        el: $('#send-message'),
        template: _.template(messageSendTemplate),
        events: {
            "click #send": "sendMessage",
            "keypress #field": "sendMessageOnEnter",
        },
        initialize: function () {
            _.bindAll(this,'render', 'sendMessage', 'sendMessageOnEnter');
            this.render();
        },
        render: function () {
            this.$el.html(this.template);
            this.delegateEvents();
            return this;
        },
        sendMessage: function () {
            var Message = Message.extend({
                noIoBind: true
            });
            var attrs = {
                message: this.$('#field').val(),
                username: this.$('#username').text()
            };

            var message = new Message(attrs);
            message.save();

            /*
        socket.emit('message:create', {
            message: this.$('#field').val(),
            username: this.$('#username').text()
        });
        */

            this.$('#field').val("");
        },
        sendMessageOnEnter: function (e) {
            if (e.keyCode == 13) {
                this.sendMessage();
            }
        }
    });
    return MessageSendView;
});

When keypress event is triggered by jquery and sendMessage function is called - for some reason Message model is undefined, although when this view is first loaded by require.js it is available. Any hints? Thanks

Upvotes: 0

Views: 295

Answers (2)

coderek
coderek

Reputation: 1870

Please see my inline comments:

sendMessage: function () {
        // first you declare a Message object, default to undefined
        // then you refrence to a Message variable from the function scope, which will in turn reference to your Message variable defined in step 1 
        // then you call extend method of this referenced Message variable which is currently undefined, so you see the point
        var Message = Message.extend({
            noIoBind: true
        });
        // to correct, you can rename Message to other name, e.g.
        var MessageNoIOBind = Message.extend ... 
        ... 
    },

Upvotes: 1

Hacknightly
Hacknightly

Reputation: 5154

My guess is that you've bound sendMessageOnEnter as a keypress event handler somewhere else in your code. By doing this, you will change the context of this upon the bound event handler's function being called. Basically, when you call this.sendMessage(), this is no longer your MessageSendView object, it's more than likely the jQuery element you've bound the keypress event to. Since you're using jQuery, you could more than likely solve this by using $.proxy to bind your sendMessageOnEnter function to the correct context. Something like: (note - this was not tested at all)

var view = new MessageSendView();

$('input').keypress(function() {
  $.proxy(view.sendMessageOnEnter, view);
});

I hope this helps, here is a bit more reading for you. Happy coding!

Binding Scopes in JavaScript

$.proxy

Upvotes: 0

Related Questions