adobe flex static function reference control - apache-flex

Is it possible to reference a control in an application from a static function?
What I have is a Viewstack containing VBoxes stored in separate controls. Ex:
<mx:ViewStack id="content" width="100%" height="100%" resizeToContent="true">
<controls:Login/>
<controls:Dash/>
<controls:Input/>
<controls:Review/>
<controls:Search/>
</mx:ViewStack>
Once I get logged in on my login control, I would like to change the selected index of my ViewStack. From my outside controls, I cannot reference my ViewStack by name. I can reference a public static function from an outside control however I cannot refer to the ViewStack from within that function. Any help is greatly appreciated.
JH

Normally you can have a singleton class where you can save the
instance of the main application and if you view stack is resides
inside your main application then you can do some thing like this
public static function changeIndex(index:int):void
{
FlexGlobals.topLevelApplication.content.selectedIndex = index;
//urappinstance.content.selectedIndex = index;
}

You could reach it starting from FlexGlobals.topLevelApplication (if it is visible from there). Although, the design of such a thing may be questionable.

Is it possible to reference a control in an application from a static
function?
Generally no. A static function (or property) exists on the class itself. Whereas MXML Children--such as in a view stack--exist on a specific instance of the class. A class level function will know nothing about any specific instances of the class and will not be able to access properties on a specific instance.
However, you can pass an instance of a class into a static function and access the properties that way. something like this:
public static function doStuff(myViewStack:ViewStack):void{
trace(myViewStack.id)
// do other stuff
}
And call it like this:
MyClass.doStuff(content)

Related

How to pass an object from one page component to another page component in a .NET Blazor app?

I have a .NET Blazor Server app and need to pass an object from one component to another. Both components are pages, meaning that they have #page directives with routes. I know how to use cascading values to pass a parameter between regular Blazor components, but this does not work with page components. I also know how to pass a parameter within an endpoint route. However, instead of a string or int I want to pass an object with multiple properties and am unsure how to best accomplish this.
Is it possible to pass an object as an endpoint route parameter? If not, what is a good way to accomplish this within a Razor components context?
Using dependency injection would likely solve this issue for you.
Example:
Create a class called "ApplicationService"
Create an interface in that class called "IApplicationService"
You could have something like this
public interface IApplicationService
{
public Task MsgBox(string value);
}
In the ApplicationService class inside the "ApplicationService.cs" file, go ahead and implement the interface member above.
You could have something like this:
public async Task MsgBox(string value)
{
await _JSRuntime.InvokeAsync<string>("alert", value);
}
In the program.cs class, you need to now register that "service" we just created.
You could have something like this
builder.Services.AddTransient<IApplicationService, ApplicationService>();
builder.Services.AddScoped<ApplicationService>();
In your _Imports.razor you can inject the class so that the pages have access to it:
#inject ApplicationService MainAppService;
Now in your razor components you should be able to do something like this:
await MainAppService.MsgBox("This is a message box");
This works in my WASM blazor app, hope it sheds some light on the server side of things 🚀
Use a DI service. Create a class to hold your object. Add it as a Scoped Service in Program. Use it in any component (pages are just components with a page attribute) though #inject.

Difficulty copying/extending singleton manager class

I want to extend or copy the PopUpManager class to add the ability to keep track of the number of windows.
I just want to add a simple windowCount++ when a window is added and windoCount-- when it's removed.
the problem is PopUpManager is a Singleton class... I wasn't able to make it work properly by extending it. And now I have tried to copy the code from the PopUpManager.as file and just add my variable to the end of its functions. It doesn't seem to be working though since it says my properties are undefined even though they are declared above the constructor.
I am thinking I would have to make a copy of the PopUpManagerImpl.as since that's wehre it seems much of the business resides (PopUpManagerImpl extends EventDispatcher implements IPopUpManager) would that allow me to have access to the variable? and should I ignore the manager and just put it in the implementation class?
here is a link about Using the Flex Singleton register, which helped me out when finding myself in the same situation.
I hope you can inspire from that too.
You likely didn't declare yours properties as static. The PopUpManager uses all static methods - this is why working with it you use syntax like:
PopUpManager.createPopUp(...
instead of
var popUpManager:PopUpManager = new PopUpManager();
popUpManager.createPopUp(...
This means that any variables declared in the PopUpManager need to also be static so as to be accessible at the class level.
public static var windowCount:int

call flex initComplete at a specific time

Below is the overriden on complete function for a preloader in Flex.
private function initComplete(e:Event):void
{
//dispatchEvent(new Event(Event.COMPLETE));
cp.status.text="Configuring... Please Wait";
}
What I want to do is when the app has finsihed loading I want to change the preloaders text to "configuring".
Then I want to go and do a bunch of setup stuff in my code.
Once I've done all the setup I wanted how can I get the Preloader to dispatch its Event.complete from else where in my code?
I tried Application.application.preloader but it comes up null.
So I guess my question really is how to access a preloader from anywhere in my application.
Would a better approach be to have all setup classes as members of my preloader class?
One thing that might help is a Model-View-Controller pattern. Are you using a framework for your application like Mate, Swiz, or Cairngorm?
If you were using Mate, for example, you could do something like this:
Create an AppStateManager class with a property (e.g. applicationState)
Create an EventMap with an EventHandler for the FlexEvent.INITIALIZE event. In this handler, set the AppStateManager.applicationState to something like "CONFIGURING"
Your EventMap has an injector that injects the applicationState property into a view. The injector listens for changes to this property and updates the view. In this case it might just be injected into your main view.
In the main view, you have a public bindable property also called applicationState that gets injected by Mate.
In the setter for this property, you can have an if/then or a switch that does different tasks depending on the state. For example, if applicationState == "COMPLETE", then this.preloader.dispatchEvent(Event.COMPLETE) or something like that.
The details are pseudo-sketched out but the idea is to use Flex's bindings to notify view components when changes have been made, and to have shared objects that maintain state. Not sure if that's what you're looking for...
The component LifeCycle does specific stuff in a specific order, and the near final element is to make the component visible.
It sounds to me like you want to defer this setting of visible to true to do other stuff. But, I imaging if you were making use of the component LifeCycle this would be a non-issue.
What sort of app init stuff do you need to do?

custom flex component, visual controls in design view

Do you know how if you drag an <mx:Label> or <s:Label> component into your Flex project, when you go to design mode you get this panel on the right to set its properties like text etc.
I have a custom component that I can call with actionscript, or with mxml like this:
<comps:TheComp field1="OK" field2="Yes" />
The component takes this input and uses it for its internal operation
private var field1:String;
private var field2:String;
private function initializeit()
{
// component takes the input and lays it out as needed
}
When I go to design mode, I can see the component under custom components, I can drag it to the stage and see it, but can't set its values field1 and field visually on the right like a normal <s:Label> or <mx:Label> would have.
Any idea how I can add that? Do I need to make it inherit something or anything else
Try using the [Inspectable] metatag in your code
[Inspectable]
private var field1:String;
[Inspectable]
private var field2:String;
Not sure if inspectable members can be private. If [Inspectable] alone doesn't do it, try making the vars public or protected.
You need to put any custom components you want to view this way into a library project and make a swc out of it, then use the swc instead of just the source code http://blog.another-d-mention.ro/programming/create-professional-flex-components/ .
HTH;
Amy
Those variables must be public. Variables are accessible from properties panel after setting them public.
public var field1:String;
public var field2:String;

How do I make a field global to my site?

Okay, this is a bit abstract, but here goes:
I'm creating a website and I want to have a field, "foo", that I can access from any page on the site. I figured the best way to do this would be to create a subclass of Page called "bar", add the protected field "foo" to it, and then have all my webpages inheret from "bar". Ta-da. Every page now has foo.
But now I add controls to my pages, and I want them to have access to "foo".
Well, now foo can't be protected, so it's public. Fine. But how do the controls know about "foo"? I can access foo by doing something like this in my control:
Foo foo = ((Bar)Page).foo;
This works, but strikes me as a bit ugly. I'd really like to just be able to use foo. I figure, hey, maybe I can do the same trick with my controls that I did for page. I create a new class, "blargh" that inherits from UserControl, and grab foo in there the ugly way. Then I have my controls inherit from blargh. Yay!
Except it doesn't work. When I start up the project it complains about the line trying to access ((Bar)Page).foo, because Page is null. Why? How could Page be null? When I look at the call stack I get no help.
Is there an easy, well understood way to do this? Am I barking up the wrong tree?
Another easy way to get started with this, before you decide which objects will need access and which won't, is to simply make a public static class to hold this and other global objects. Something like:
public static class Globals
{
public static Foo foo = new Foo();
}
If you need every user to have their own instance you can store it in the session.
Session["foo"]=data;
Then on your other pages you can use:
Control ctl = (Control) Session["foo"];
Keep in mind you will have to cast Session["foo"] to whatever type you want to work with. there is also a similar Application[] space which can be used if you only need one instance for every user of the website.
What do you need access to? If its data, why not put the value of foo in the Session? Then it can be accessed from anywhere.
One option to look at is to extend the page class using extension methods
Then Page will have Foo available whenever there is an instance of Page. Depending on what Foo is doing you will probably still need to store the data in session.
As for why Page is not available in your control. The Page property is only populated once the control has been added to the page. If your control does not sit directly on the page, then it is when it's anscetor that does sit on the page is added to the page.
You have to determine if this [foo] is going to be the same for all users or if it is specific to a single user. If it is the same for all, a Static class with static variables will solve this for you.
public static class FooClass {
public FooClass() {
}
public static string FooName = "TheFoo";
}
If you are looking at something that is going to be specific per user, I would recommend using the Session to store this. You could put your FooClass into the session as well, its really up to you as to what you're putting there.
FooClass myFoo = Session["CurrentFoo"] as FooClass;
Is foo the same value shared globally, or does it vary for each page?
I see two possibilities you might like:
Put it into the Application object of ASP.Net (I don't remember exactly where it hangs in asp.net, but with that name you can find doc on it). This would be for a global value that does not vary.
Make it an extension method on Control. Page ultimately inherits from Control, so it will be available. Like this:
public static class ControlExtensions
{
public static Foo foo(this Control self)
{
return foo;
}
}
Now UserControls and Pages should be able to get to it.

Resources