Unbreakable Unbreakable - 3 months ago 7
HTML Question

How to call a module again in Javascript/Backbone which is already loaded

I am new to Javascript/backboneJS/RequireJS. In order to render my front end I have made one controller, one model and one view. Also, I have one dropdown in my html file.

So what I have done till now is in my html file at the END I have

require(['common'],function()
{
require(['jquery','fastclick','nprogress','charts','underscore','spinner'],function()
{
require(['firstDashboardController']);
});
});


So I am loading "firstDashboardController" and this controller loads all the modules accordingly and displays data in front end. So everything works fine.

Now I have a dropdown in the front end. When I select the dropdown, as per the id selected I want to retrieve the data. So I need to call "firstDashboardController" again so that everything gets rendered as per the new id that I have got.

So what am I suppose to do? Like do I need to UN-REQUIRE my "firstDashboardController" and then REQUIRE it again passing the new id. Because the controller is already loaded via Require beacuse I loaded it in my HTML file as mentioned above. But I need to load it again as per the new id selected it via dropdown. So how to go about it? Pleas help me. if any code snippet is required I can put that.

Code Snippet:

My Controller:

define(['backbone', 'firstSubViewModel','dropdownViewModel', 'dropdownModel'],
function(Backbone, firstSubViewModel, dropdownViewModel, dropdownModel) {

var ch = new dashboardModel.chart({});
if (localStorage.getItem('p_kt') && localStorage.getItem('p_acid') && localStorage.getItem('p_seid')) {
var data = {
tokenProp: localStorage.getItem('p_kt'),
accountIdProp: localStorage.getItem('p_acid'),
sessionIdProp: localStorage.getItem('p_seid')
};
$.when(
ch.fetch(data) // GETTING DATA FROM MODEL VIA AJAX CALL in my model.JS

).then(function() {
// Main Graph on Dashboard
new firstSubViewModel({
el: '#chartAnchor1',
model: ch
});
});});


I somehow need to call
ch.fetch()
again.

Answer

You aren't properly defining your controller. You currently have it as sort of a one-time setup method instead of something you can re-run later. Let's go step by step.

myLife.js:

define([], function() {
  return "a complex series of failures";
});

By returning a value from define's callback, this defines that anytime I require "myLife", then it will provide "a complex series of failures" in the callback function. This is what Backbone and other AMD modules do to appear inside your code blocks. However, it only runs the contents once; and saves the result. So, this won't work:

incrementer.js:

var x = 0;
define([], function() {
  x = x + 1;
  return x;
});

(Trying to require incrementer would always give you "1".)

What you want to do is return a function - one you can re-run anytime.

incrementerV2.js:

define([], function() {
  var x = 0;
  return function() {
    x = x + 1;
    return x;
  };
});

In any file, you can then have this:

require(['incrementerV2'], function(myIncr) {
  myIncr(); // 1
  myIncr(); // 2
});

...And, for the record, I would recommend having only one require statement in any given file whenever possible. You can add dependencies in that first-argument array if load order is important.

More commonly, people will have one module contain a self-defined object that has multiple functions in it, rather than the function I gave above. Returning and then using just one function is valid as well, depending on the use case. Any variable type works, but just remember it will always be the one and only same variable anytime you later need it.

Comments