I have some comments for discussion on this one, so I thought it easiest to post them here than in the comment on Servoy Magazine...
Adrian, thanks for taking the time to put this all together. I do have a few issues with it though...
1. Why are you using the SolutionModel and cloning the form? application.createNewFormInstance is faster, and should have less overhead as it just creates a new runtime instance, whereas using the SolutionModel and cloning the form is touching the blueprint and runtime.
2. Your encapsulation examples aren't using encapsulation. In your examples, the end result is still calling code like forms[formName].methodName(). The only difference is that you are getting the form name dynamically. Instead, if you want to call methods across forms, you should be using an event based registration based model. So if the child form wants to call something in the parent form, then in the onLoad of the parent form, it should register its method with the child form. Then when the child form wants to do a call, it looks to see what methods are registered, and calls them. Servoy's new frameworks they will be coming out with soon will implement these techniques in their framework, so I'd suggest people take a look at those. Generally, if you have code in your solution that does forms.formName.* then there is a problem. I know we all get lazy sometimes and do this, but its really not the right way, and shouldn't be taught. Even if formName is dynamic forms[formName].methodName() is still wrong. If you think of forms like View in the MVC architecture, your having code in one view directly call another view without going through the model, and thats not ideal. Code in a form should only directly call code within itself, in a scope, in an entiy method, or a method object that has been registered via an event base registration model (like using callbacks and listeners). Some pseudo code below about the event registration model with listeners...
- Code: Select all
--in parent Invoice form
function onLoad(){
//an example scope that tracks events by a name, and which methods are listening
scopes.events.registerListener(myListener, "InvoiceLinePriceUpdated")
}
function myListener(){
//do something here on parent form, like update a total for amount owed
}
--in the child InvoiceLines form
function price_onDataChange(){
//an example scope that triggers the event to run, which should execute all the methods that are listening
scopes.events.fireEvent("InvoiceLinePriceUpdated")
}