Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a backbone view function from another view in separate files

I have two backbone views defined in two separate files namely: LandingView.js

define([
    'jquery',
    'underscore',
    'backbone',
    'marionette',
    'text!templates/landing/landingTemplate.html',
    'text!templates/invitations/invitationsTemplate.html',
    'views/invitations/InvitationsView',
], function ($, _, Backbone, Marionette, landingTemplate, invitationsTemplate, InvitationsView) {
var LandingView = Backbone.View.extend({
        el : $("#landing"),
        id : 'landing',
        transition : 'slide',

        initialize : function () {              
            this.GetNotificationsCounts();
        },
        events : {
            'click #invitations' : 'onInvitations',

        },
        render : function () { 
            var that = this;
            $('.menu li').removeClass('active');
            $('.menu li a[href="#"]').parent().addClass('active');

            this.$el.html(landingTemplate);

        },
        cleanup: function() { 
            this.undelegateEvents();
            $(this.el).empty();
        },
        onInvitations : function () { 

            //do something
        },

        GetProfile: function (userLogin) {
               // do something
        },


        GetNotificationsCounts: function () {
               // do something

        },

        formatAccountName: function () {
             //do something
        }


    });

return LandingView; });

Then there is another file InvitationsView.js

define([
    'jquery',
    'underscore',
    'backbone',
    'marionette',
    'views/landing/LandingView',
    'text!templates/invitations/invitationsTemplate.html',
], function ($, _, Backbone, Marionette, LandingView, invitationsTemplate ) {


var InvitationsView = Backbone.View.extend({
        el : $("#invitations"),
        id : 'invitations',
        transition : 'slide',

        initialize : function () { debugger;

            this.$el.attr('data-transition', this.transition);
            this.currentUserLogin = currentUserLogin;
            var that = this;

        },
        events : {

        },
        render : function () { debugger;
            $('.menu li').removeClass('active');
            $('.menu li a[href="#"]').parent().addClass('active');

            this.GetUserInvitationDetails();

             this.$el.html(invitationsTemplate);

        },
        cleanup: function() { 
            this.undelegateEvents();
            $(this.el).empty();
        },

        GetUserInvitationDetails: function () {

            var landingView =  new LandingView();
            currentUserName= landingView.formatAccountName();
            curUser = currentUserName.replace("\\", "^").replace("^", "%5E");

            var profilemsg = landingView.GetProfile(currentUserName);

        },

    });

return InvitationsView;});

Now I need to call the formatAccountName and GetProfile functions defined in the first JS to the second JS. I am unable to do that. I get errors. When I try

var landingView = new LandingView(); currentUserName= landingView.formatAccountName();

This also fails. Can somebody help me in this regard and tell me how can I achieve this

like image 893
ConfuXigrator Avatar asked Mar 17 '23 22:03

ConfuXigrator


1 Answers

Your current approach of calling the formatAccountName method works. The following jsfiddle shows this:

http://jsfiddle.net/v4h11qac/

The problem is likely caused by another error that has not been handled correctly, resulting in the code not being run. You should fix the existing errors and the method call should work as expected.

Orignal Answer:

You could call the method directly on the prototype object:

LandingView.prototype.formatAccountName();

If you need to pass through a new context you can use the call or apply method as below:

LandingView.prototype.formatAccountName.call(context);

A better approach might involve creating a helper module that can be shared by both views.

var viewHelpers = {
    formatAccountName: function(account) {
        // ...
    }
};

var ViewOne = Backbone.View.extend({
    render: function() {
        var formattedName = viewHelpers.formatAccountName(this.model);
        // ...
    }
};


var ViewTwo = Backbone.View.extend({
    render: function() {
        var formattedName = viewHelpers.formatAccountName(this.model);
        // ...
    }
};

You could also use a system bus, however that may be a little too heavy for such a use case. If you want to take a look at that path, then Backbone.Radio provides a request/response pattern which could be used to fulfill this requirement.

like image 62
KarlPurk Avatar answered Apr 06 '23 02:04

KarlPurk