I have a module that has 2 sub module dependencies. In the parent module there is a method that I would like to call from both child modules. How could I do that?
Is there another way then passing the parent module object to the child module constructor?
define(['child1', 'child2'], function (child1, child2) {
return {
init: function () {
child1.init();
child2.init();
},
parentMethod: function() {
console.log('called');
}
}
});
/*child1*/
define(function() {
return {
init: function() {
//call parentMethod()
}
}
});
/*child2*/
define(function() {
return {
init: function() {
//call parentMethod()
}
}
});
RequireJS has no notion of parent-child relationship between modules. Given that modules are singletons, and that a module like child1 could be loaded by multiple modules (for instance, loaded by parent1 and parent2), then which module should RequireJS consider to be the real parent of child1?
Passing a reference to the parent to your children's init() function is really the way to go.
Related
Questions: I am trying to access the methods available in module.export from our side of same programe
in below progrme , i have method a available inisde module.export trying to access from our side in same file
//Module.export section
module.export = {
a: function (){ // Function a
console.log('My name is abc');
}
}
function b(){ //Trying to access the method out side of module.export
// How to access the function a from this metod
}
If I understand correctly, it is just this simple (only it should be module.exports, not module.export):
module.exports = {
a: function (){
console.log('My name is abc');
}
}
function b(){
module.exports.a();
}
You will have to store it in a variable first, then you can access it in same file too:
// save in to variable, and export (both things in 1 line)
var abc = module.export = {
a: function () { }
}
function b() {
// access your module here
abc.a();
}
I have two .js files: root.js and external.js
root.js
import myExternalFunction from 'external.js'
class Parent {
constructor(){}
parentFunction = () => {
console.log('I was called from an external function using "this."')
}
}
external.js
export default myExternalFunction = () => {
this.parentFunction()
}
Currently I receive an error about it not being a function, or no access to 'this'.
How do I import external functions that want to use the 'this' scope from which they are being called?
How do I import external functions that want to use the 'this' scope from which they are being called?
It doesn't have anything to do with how you export/import the function.
There are two things you need to consider:
functions that want to receive their this value dynamically must not be arrow functions, so use
export default function myExternalFunction() {
this.parentFunction()
}
as usual, the function must be invoked in the right way to get the expected this value. There's no magic that passes the current this value in the scope of the call to the called function. You'll have to do something like
import myExternalFunction from 'external.js'
class Parent {
constructor(){
this.method = myExternalFunction;
this.parentFunction = () => {
console.log('I was called from an external function using "this."')
}
}
}
const example = new Parent;
example.method() // an invocation as a method
myExternalFunction.call(example); // explicit using `call`
What's the best way to pass thisArg to a require()d module?
I want to do something like this:
index.js
function Main(arg) {
return {
auth: auth,
module: require('/some/module')
}
}
module.js
module.exports = {
someMethod: function() {...}
}
Then, in my code somewhere I call Main(), which returns the object.
So Main().auth exists, cool. But how do I access it from Main().module?
The thisArg in Main().module.someMethod() points to the module itself.. but I need the parent.
Is there any way to do this without using new keyword, functions and prototypes?
EDIT:
Thanks for all the answers guys! Some additional info:
Main() is the module what I wanna require() and use in my app. The "module" Main tries to import is actually just sub functionality of Main, it's just a part of code which I moved to a separate "module" to better organize the code.
So a better example would be:
function RestApi(param) {
return {
common_param: param,
commonFunc: function() {...}
endpoint1: require('/some/module'),
endpoint2: require('/some/module2'),
endpoint3: require('/some/module3')
}
}
And my app would use it like this:
RestApi = require('./RestApi')
RestApi().endpoint1.someHTTPCall(...)
But inside someHTTPCall(), both "common_param" and "commonFunc" should be accessible via thisArg, like this.commonFunc().
So this is kinda a general question, how do you merge multiple modules using require() properly, so "this" would point to the right object (i.e.: the parent)
I know this could be achieved using Function.prototype and inheritance, just would like to know if there is a simpler way.
The best I found so far is something like this:
var _ = require('lodash');
function Module(auth) {
this.auth = auth || {};
}
Module.prototype = {
endpoint1: function() { return _.extend(require('./endpoint1'),{auth: this.auth, commonFunc: commonFunc})}
}
function commonFunc() {...}
However, this is not ideal, since RestApi.endpoint1() would create a new the object on every call.
Is there a better way to handle this?
Thanks in advance!
Create own "require" module with auth param and allways use it.
project/module/require2.js
module.exports = function(path, auth){
if (!check(auth))
return null
return require(path)
}
You could change the module to return a function, like this:
// some/module.js
module.exports = function(mainModule) {
var main = mainModule;
return {
someMethod: function() {
main.doSomethingElse();
}
}
}
Then require it passing the main object:
function Main(arg) {
var main = {
auth: auth,
other: stuff,
};
main.module = require('/some/module')(main);
return main;
}
Suppose I have the following code:
foo();
function foo() {
func1("bla", function() {
console.log("done!");
});
}
function func1(value,callback) {
process.nextTick(callback);
}
Will the function above will be totally async ?
Or should I use this foo function? :
function foo() {
process.nextTick(function() {
func1("bla", function() {
console.log("done!");
});
}
Actually my question is if the parent blocks the child process from being Async ?
The first option is going to be "async" in the sense that node might do other things before calling the callback method.
There is no need to call the second method. As soon as your foo function finishes and any parent callers of foo finish node will start doing other work, which eventually will be the work registered by nextTick.
I'm trying to load and render additional views async and append them to the ItemView.
Simplified code - why is $el not defined in the require() block in render() - what am I missing here? Am I not using RequireJS properly, or Marionette, or just my inexperience with javascript?
What is the recommended way of doing this? It needs to be dynamic as additional section views could be available at runtime that I don't know about yet as registered by plugins.
define(['require','marionette', 'App', 'swig', 'backbone.wreqr','text!./settings.html'],
function (require,Marionette, App,Swig, Wreqr, settingsHtml )
{
var sectionViews = ['./settingscontent/GeneralView'];
var SettingsView = Marionette.ItemView.extend(
{
template: Swig.compile(settingsHtml),
commands: new Wreqr.Commands(),
initialize: function ()
{
this.commands.addHandler('save', function (options, callback)
{
callback();
});
Marionette.ItemView.prototype.initialize.apply(this, arguments);
},
render: function()
{
Marionette.ItemView.prototype.render.call(this);
var $el = this.$el;
var self = this;
require(sectionViews, function (View)
{
$el.find('div.tab-content').append(new View(self.model).render().$el);
// $el is not defined
// self != outer this - $el is an empty div
});
return this;
}
}
return SettingsView;
})
Why are you trying to overload itemview.render?
Why not use the built in onrender event
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.itemview.md#render--onrender-event
from that documentation :
Backbone.Marionette.ItemView.extend({
onRender: function(){
// manipulate the `el` here. it's already
// been rendered, and is full of the view's
// HTML, ready to go.
}
});
seems easier and more typical of marionette usage
You need to bind this inside the function to the SettingsView object. Something like:
render: function()
{
Marionette.ItemView.prototype.render.call(this);
var $el = this.$el;
var self = this;
require(sectionViews, _.bind(function (View)
{
...
}, this));
return this;
}
The local variables will not be visible inside the bound function. You can use this and this.$el safely however.