I'm not only relatively new to JavaScript but also to RequireJS (coming from string C# background). Currently on my web page I have a number of JavaScript functions. Each one takes two arguments. Imagine that they look like this:
functionA(x1, y1) { ... }
functionB(x2, y2) { ... }
functionC(x3, y3) { ... }
Currently, these functions exist in a tag on my HTML page and I simply call each as needed.
My functions have dependencies on KnockoutJS, jQuery, and some other JS libraries. I currently have Script tags that synchronously load those external .js dependencies. But I want to use RequireJS so that they're loaded asynchronously, as needed. To do this, I plan to move all three functions above into an external .js file (a type of AMD "module") called MyFunctions.js. That file will have a define() call (to RequireJS's define function) that will look something like this:
define(["knockout", "jquery", ...], function("ko","jquery", ...) {???} );
My question is how to "wrap" my functionA, functionB, and functionC functions where the ??? is above so that I can use those functions on my page as needed. For example, in the onclick event handler for a button on my HTML page, I would want to call functionA and pass two it two arguments; same for functionB and functionC.
I don't fully understand how to expose those functions when they're wrapped in a define that itself is located in an external .js file. I know that define assures that my listed libraries are loaded asynchronously before the callback function is called, but after that's done I don't understand how the web page's script tags would use my functions. Would I need to use require to ensure they're available, such as:
require(["myfunctions"],function({not sure what to put here})]
I think I understand the basics of RequireJS but I don't understand how to wrap my functions so that they're in external .js files, don't pollute the global namespace, and yet can still be called from the main page so that arguments can be passed to them. I imagine they're are many ways to do this but in reviewing the RequireJS docs and some videos out there, I can't say I understand how...
Thank you for any help.
Just let your MyFunctions.js file return an object to which you have added the methods you want to expose, like so:
define([], function(){
function myPrivateFunction(){
console.log('in private function');
}
function myPublicFunction(){
console.log('in public function');
}
function myOtherPublicFunction(){
console.log('in the other public function');
}
return {
functionA: myPublicFunction,
functionB: myOtherPublicFunction
};
});
The name you give the parameter to your function which requires the MyFunctions
does not matter at all. The name strings and the order of the strings in the dependency array does matter, as does the order of the parameters to the function, but the names of the parameters does not. E.g.
require('myFunctions', 'knockout', 'jquery', function(myFunctions, ko, $){
//here we can use the myFunctions, ko and $ variables.
//To call the public function, use the name which the function was
//exposed as; functionA
myFunctions.functionA();
});
The above sample code works exactly the same as the following:
require('myFunctions', 'knockout', 'jquery', function(my, k, j){
//In this example, your functions will be on the value of the 'my' variable,
//knockout will be the value of the 'k' variable and jQuery will be the
//value of the 'j' variable.
//To call the public function, use the name which the function was
//exposed as; functionA
my.functionA();
});