How to access the function of different controller? - JavaScript MVC

1.3k Views Asked by At

Assume I have 2 controllers that handle 2 parts of the page - header and page content. Most of the actions happen in pagecontent.js (controller for page content). It has set of functions to load various views. But header has the back button. I track the history, and when the back button is clicked, I want to call the appropriate function on pagecontent.js to load particular view. Here's the example of what I'm trying to do:

pagecontent.js

$.Controller('Controller.Pagecontent', {
  ...
  ".home click": function(){
      this.loadHome();
  },
  loadHome: function(){
      $('#pagecontent').html('//views/home', {});
  }
  ...
})

header.js

$.Controller('Controller.Header', {
  ...
  ".back click": function(){
      if( HISTORY[0] == 'home' )
          // call loadHome() from pagecontent.js
  }
  ...
})

I don't want to copy all those functions to header.js because it will be redundant and some functions have complex logic.

Any ideas?

4

There are 4 best solutions below

0
On BEST ANSWER

You can access other controllers functions/events using prototype. Eg. in this situation, it would be like this:

$.Controller('Controller.Header', {
  ...
  ".back click": function(){
      if( HISTORY[0] == 'home' )
         Controller.Pagecontent.prototype.loadHome();
  }
  ...
})
0
On

If js code is going to differ per page and if it is less then make use of inline js or add those lines of code in separate file and include it inside layout (assuming you have different layout so that same js file is not getting loaded everywhere)

1
On

Any defined object in javascript may be accesible from any javascript code in browser's page.

If you load two .js files in the same page although in different parts objects in one may be accesible in the other so those may be defined in window object.

file1.js

var a = 13;
var b = 14;

file2.js

alert("a="+a);

function show_b() {
    alert("b="+b);
}

The alert with 'a=13' will be shown if file2.js is loaded after file1.js. The one with 'b=14' will be shown whenever you call show_b() before both files are loaded.

To avoid interferences you can use windows.a and windows.b instead of a and b.

The same example works with function definitions.

0
On

There are lots of ways to share code, but the idiomatic way in JavaScriptMVC would be something like:

".back click": function(){
  if( HISTORY[0] == 'home' )
     $('#pageContent').controller().loadHome();
}

where #pageContent is the selector you used to create the controller in the first place.

Even better would be to use a custom event. You can use jQuery.trigger if pageContent is a parent of header:

// PageContent

"home.clicked": function() {
   this.loadHome();
}

// Header

".back click": function() {
  this.element.trigger('home.clicked');
}

Or you can use an OpenAjax event:

// PageContent

"home.clicked subscribe": function() {
   this.loadHome();
}

// Header

".back click": function() {
  OpenAjax.hub.publish('home.clicked');
}