Calling/Accessing a function in one module from another

Questions, tips and tricks and techniques for scripting in Servoy

Calling/Accessing a function in one module from another

Postby Chuck.Amata » Fri Jan 29, 2010 9:07 pm

I am trying to use one module (navigation framework ) to fire a method on a form in another module. I can't seem to find a way to expose or pass the form method I would like to call to this module though.

This is what I've tried:
1. Establish a global module variable in module 1 and a global method in module 1 to set the variable to point at a method in module 2. When a button is pressed in a form within module 1, the onAction form method in module 1 calls the form method (preferred) in module 2 using the global variable.

I've looked at the solution model and the currentController functions and have tried a number of combinations that seem to make sense to pass the required information but to no avail.

Any insight or ideas would be greatly appreciated.
Chuck.Amata
 
Posts: 50
Joined: Sun Oct 04, 2009 8:02 pm
Location: USA

Re: Calling/Accessing a function in one module from another

Postby jgarfield » Fri Jan 29, 2010 9:55 pm

It sounds like you need to include the "other" module in the navigation framework.

You should be able to do this via the Solution's properties panel, specifically the moduleNames property.

Once you've added the module in, you should just be able to directly access the form method like so

Code: Select all
forms.myFormName.myMethodName()
Programmer.
adBlocks
http://www.adblocks.com
jgarfield
 
Posts: 223
Joined: Wed Sep 28, 2005 9:02 pm
Location: Boston, US

Re: Calling/Accessing a function in one module from another

Postby ROCLASI » Fri Jan 29, 2010 10:00 pm

Hi Chuck,

You can call methods in other submodules just fine. But if you want to call a method of a module that your module is a submodule of then you have a challenge.
How is this?
The scope of modules are downwards. In other words a module can only see it's objects and from it's submodules. Not from the modules that itself might be part of (upward scope).
In the following diagram module2 has no knowledge of objects in module1 and the main solution. And module1 doesn't know of the objects in the main solution. They can only 'look' downwards. The main solution does see all objects of both modules.

submodules1.png
submodules1.png (6.73 KiB) Viewed 10633 times


Now in the next diagram modules 1 and 2 are submodules of the main solution. So both the modules see ONLY their own objects. The main solution however does see all objects of both modules.

submodules2.png
submodules2.png (5.85 KiB) Viewed 10631 times


Oddly enough this is only a restriction when you are developing because when Servoy loads your solution with all it's submodules then it considers all the loaded objects as one solution (in memory).
This is also the reason that you could use an eval() to trigger a method in a module higher up to (module) tree.

So how to work around this?

Well you can go the eval() route and call methods using eval("forms.formName.methodName()").
But that is pretty cumbersome.

Another way would be to use a link module that links all modules.
How does this work ?

You create another module in your workspace that has nothing else than modules referenced.
So in this case the linkmodule has solution, module1 and module2 as it's submodule.

linkmodule.png
linkmodule.png (7.78 KiB) Viewed 10632 times


So that's it ?
No, now you reference the linkmodule in all modules (and solution).
So the linkmodule will be the (only) submodule referenced by all other modules.

Now you have a situation where every module is referenced (by way of the linkmodule) to each other.
This way you 'flatten' the scope of the modules and everybody sees everybody.

Next time you add a new module to your solution you only have to reference it in the linkmodule and *BOOM* all other modules see it. :)

Hope this helps.

P.s. the credit for this little trick goes to the STB people.
Robert Ivens
SAN Developer / Servoy Valued Professional / Servoy Certified Developer

ROCLASI Software Solutions / JBS Group, Partner
Mastodon: @roclasi
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5438
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: Calling/Accessing a function in one module from another

Postby Chuck.Amata » Fri Jan 29, 2010 10:21 pm

Thank you very much for the quick reply. This explains exactly what I was seeing.
Chuck.Amata
 
Posts: 50
Joined: Sun Oct 04, 2009 8:02 pm
Location: USA

Re: Calling/Accessing a function in one module from another

Postby pbakker » Sat Jan 30, 2010 11:22 am

Well you can go the eval() route and call methods using eval("forms.formName.methodName()").
But that is pretty cumbersome.


eval() == evil!

Not saying you should use this hack to access objects in the parent solutions/modules if you're module structure is not correct, but if you do something like this, do it the correct way:
Code: Select all
forms['formName']['methodName']()


Paul
pbakker
 
Posts: 2822
Joined: Wed Oct 01, 2003 8:12 pm
Location: Amsterdam, the Netherlands

Re: Calling/Accessing a function in one module from another

Postby ROCLASI » Sat Jan 30, 2010 11:52 am

Ah, of course. Almost forgot about that.
I stand corrected.
Robert Ivens
SAN Developer / Servoy Valued Professional / Servoy Certified Developer

ROCLASI Software Solutions / JBS Group, Partner
Mastodon: @roclasi
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5438
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: Calling/Accessing a function in one module from another

Postby jcompagner » Thu Feb 04, 2010 3:06 pm

what is exactly the use of a module if you make circular references and you just point everything to everything?

Then thats nothing more then a (one) big solution, so then you could just have had one big solution.....

in my eyes if you have solution -> module
and you want to let the model call stuff from the solution there is only one good way
The solution should register callback inside the module like:

solution method:
{
global_or_form_method_of_module.registerCallback(globalmethodofsolution or formname/methodname combo)
}

then in the module method when you want to do the callback:
{
forms[solutionCallbackFormName][solutionCallbackMethodName](arguments)
}

this is just like registering listeners on events in java.
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: Calling/Accessing a function in one module from another

Postby ROCLASI » Thu Feb 04, 2010 3:26 pm

Hi Johan,

Using modules vs one big solution. When using modules you can reuse code. Simple :)
When loaded servoy considers the modules part of a solution anyway, right ? So it's just a scope issue.

Registering modules like you suggested is a proper way of programming but doing it the STB way you have the benefit of Eclipse helping you with code completion and all that. So it's easier coding.
Robert Ivens
SAN Developer / Servoy Valued Professional / Servoy Certified Developer

ROCLASI Software Solutions / JBS Group, Partner
Mastodon: @roclasi
--
ServoyForge - Building Open Source Software.
PostgreSQL - The world's most advanced open source database.
User avatar
ROCLASI
Servoy Expert
 
Posts: 5438
Joined: Thu Oct 02, 2003 9:49 am
Location: Netherlands/Belgium

Re: Calling/Accessing a function in one module from another

Postby jcompagner » Thu Feb 04, 2010 4:36 pm

ROCLASI wrote:Hi Johan,
Using modules vs one big solution. When using modules you can reuse code. Simple :)
When loaded servoy considers the modules part of a solution anyway, right ? So it's just a scope issue.


But yo can also reuse that one big solution i was talking about, so the reuse nature of code isn't gone.
Because your modules if they are completely intertwined then they are not stand alone modules
Real reuse of modules is this:

You have 3 modules that don't depend on anything.

Module X
Module Y
Module Z

Solution A uses Module X and Y
Solution B uses Module X and Z
Solution C uses Module Y and Z

If you linked X, Y and Z together then its impossible for Solution A to just use X and Z (and the other examples)
Because it has to include all of them And what is the result of that? yes one big module (X , Y and Z together)

For example a module should be able to load standalone as the active solution in serclipse
Without any errors. (it should compile by itself)
But in your case what ever module you take you always load exactly the same set, again an example that it is just one big monolithic thing.
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: Calling/Accessing a function in one module from another

Postby ptalbot » Fri Feb 05, 2010 2:43 am

jcompagner wrote:what is exactly the use of a module if you make circular references and you just point everything to everything?

Then thats nothing more then a (one) big solution, so then you could just have had one big solution.....

Quite, but it's also a way to avoid clutter in your solution explorer!
Naming conventions can help but having hundreds of forms at the same level is not always easy to use.

So you can just make modules to organize your 'big solution' in logical pieces of code that works together: like a java package inside one project.
Still everyone can see and call everyone in the same project, and that's valid too I think.
And one developer can be in charge of one module, it doesn't mean that he nevers 'links' to the solution itself.

A different (and probably more efficient) way would be if it was possible to have a hierarchy of forms inside a solution, then the need to use modules for this purpose would be less obvious. But I guess that it is not the kind of feature that will happen before Servoy 6, is it? ;-)

In the solutions we are building right now we have a few modules, like RESOURCES, NAVIGATION, etc... and none of these would easily be reusable as such, but still it is an efficient way to organize our solutions. And yer, we also have other modules like UTILS, FEEDBACK, I18N which are reusable but they are not the majority.
Patrick Talbot
Freelance - Open Source - Servoy Valued Professional
https://www.servoyforge.net
Velocity rules! If you don't use it, you don't know what you're missing!
User avatar
ptalbot
 
Posts: 1654
Joined: Wed Mar 11, 2009 5:13 am
Location: Montreal, QC

Re: Calling/Accessing a function in one module from another

Postby jcompagner » Fri Feb 05, 2010 11:47 am

we have something like that in the planning yes, dont know the target
The idea is something like gmail, that you can assign labels to the solution explorer elements, and based on those labels you can have them grouped.
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: Calling/Accessing a function in one module from another

Postby msedita » Thu Aug 04, 2011 6:09 pm

I was using the link module technique so that, for example, a module could access media, relations, etc. that exist in the calling solution ( I know that Johan doesn't like this but it works for me). Now, in Servoy 6, this displays an error in developer "a cycle was detected in the build path of project: xxxx". Is there any way to turn this error reporting off?
Michael Sedita
MS Health Software Corp.
Developers of software solutions for behavioral healthcare and social service providers.
www.mshealth.com
User avatar
msedita
 
Posts: 224
Joined: Thu Dec 13, 2007 8:01 pm

Re: Calling/Accessing a function in one module from another

Postby jcompagner » Thu Aug 04, 2011 6:24 pm

Yes we really didn't like it! :)
And i was not alone because this is not even a Servoy generated error but an 3th party one (dltk/eclipse itself)

but you can make it a warning: Preferneces-> Dynamic Languages there you have a build path problem entry
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: Calling/Accessing a function in one module from another

Postby Harjo » Thu Aug 18, 2011 5:16 pm

jcompagner wrote:in my eyes if you have solution -> module
and you want to let the model call stuff from the solution there is only one good way
The solution should register callback inside the module like:

solution method:
{
global_or_form_method_of_module.registerCallback(globalmethodofsolution or formname/methodname combo)
}

then in the module method when you want to do the callback:
{
forms[solutionCallbackFormName][solutionCallbackMethodName](arguments)
}

this is just like registering listeners on events in java.


I want to understand this, and do it right.
I have a core-module which does some core stuff, but in that method I MUST set some elements, on a form, which are in my main solution, like this:

Code: Select all
function core_onFind(vEvent) {
     //do some core stuff here, which for this example is not interesting
     //blabla
     //here it get's interesting:
        forms.menu_bar.elements.btn_back.enabled = false
   forms.menu_bar.elements.btn_home.enabled = false
   forms.menu_bar.elements.btn_mail.enabled = false
   forms.menu_bar.elements.btn_forward.enabled = false
}


If I make this module the active one, indeed Servoy gives me warning about all four lines, that It cant find the form: menu_bar, with the warning:
The property menu_bar is undefinde for the type Forms<core_module>

oke, I can fix this warning by doing this:
Code: Select all
function core_onFind(vEvent) {
     //do some core stuff here, which for this example is not interesting
        forms['menu_bar'].elements['btn_back'].enabled = false
   forms['menu_bar'].elements['btn_home'].enabled = false
   forms['menu_bar'].elements['btn_mail'].enabled = false
   forms['menu_bar'].elements['btn_forward'].enabled = false
}


but now, I loose my reference to this form: menu_bar & the 4 different elements, because it is hard-coded, right??
So how do I change this, with your suggestion: registerCallback? I have searched the forum, for this, but found zero results (only this topic, where you mentioned it)
Harjo Kompagnie
ServoyCamp
Servoy Certified Developer
Servoy Valued Professional
SAN Developer
Harjo
 
Posts: 4321
Joined: Fri Apr 25, 2003 11:42 pm
Location: DEN HAM OV, The Netherlands

Re: Calling/Accessing a function in one module from another

Postby jcompagner » Fri Aug 19, 2011 3:30 pm

how do you loose references??

They way you do it is correct, except that you code hard

forms['menu_bar']

that is just weird menu_bar is in your main solution and that code is in a module
Because menu_bar doesn't have to be there if that module is used somewhere else

if you want to do it the right way:

module:
globals.
Code: Select all
registerSomeFindFormThatDoesDefineSpecificApiSoSomeStandardElements(stringFormname) {
  mycallbackform = stringFormname;
}

then in your code or the module:

Code: Select all
function core_onFind(vEvent) {
     //do some core stuff here, which for this example is not interesting
        forms[mycallbackform ].elements['btn_back'].enabled = false
   forms[mycallbackform].elements['btn_home'].enabled = false
   forms[mycallbackform].elements['btn_mail'].enabled = false
   forms[mycallbackform].elements['btn_forward'].enabled = false
}



then in your main solution, something in the onload/onopen:

Code: Select all
globals.registerSomeFindFormThatDoesDefineSpecificApiSoSomeStandardElements('menu_bar')
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet


Return to Methods

Who is online

Users browsing this forum: No registered users and 11 guests

cron