• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 490
  • Last Modified:

History Management for desktop application

Hi,

My application(AIR application) has many mxml pages, using a carousel i can traverse b/w pages...
My requirement is for history management b/w page traversing...

I know that View stacks by default has history management set to true...

I am using View stacks  in the main page...

 
<mx:ViewStack id="mainView" width="100%" height="100%" creationPolicy="all">
		<s:NavigatorContent>
                  ****************
		</s:NavigatorContent>
		<s:NavigatorContent>
		   ***************
		</s:NavigatorContent>
		<s:NavigatorContent>
                    ******************
		</s:NavigatorContent>
		<s:NavigatorContent>
                **************************
		</s:NavigatorContent>
	</mx:ViewStack>

Open in new window


But i would like to manage the history in only few pages but not all the mxml pages i.e chid components...

View stack manage history in all pages....using viewstack itself can we manage history in only few pages where it is needed...


Thanks & Regards
0
SreeramojuPradeep
Asked:
SreeramojuPradeep
  • 10
  • 8
1 Solution
 
dgofmanCommented:
Looks I will suggest to use any MX container(s) inside ViewStack.
 s:NavigatorContent works differently I need to interstage and file bug to Adobe.
Anyway this code will create 3 containers by default and last one ViewStack will create later

if(i < 3) //add only children 0, 1, 2

You, don't need to use onChildComplete handler in your code I added for testing

 
<fx:Script>
	<![CDATA[
		import mx.core.INavigatorContent;

		private function init(event:Event):void 
		{ 
			var vs:ViewStack = event.target as ViewStack;
			for(var i:uint = 0; i < vs.numChildren; i++){
				var containerChild:INavigatorContent = vs.getChildAt(i) as INavigatorContent;
				if (containerChild && containerChild.deferredContentCreated == false){
					if(i < 3) //add only children 0, 1, 2 on initialize
						containerChild.createDeferredContent();
				}
			}
		}

		private function onChildComplete(event:Event):void 
		{ 
			trace(event.target.name);
		}
	]]>
</fx:Script>
<mx:ViewStack id="mainView" width="100%" height="100%" creationPolicy="auto" initialize="init(event)">
	<mx:Canvas name="Child1" creationComplete="onChildComplete(event)">
	</mx:Canvas>
	<mx:Canvas name="Child2" creationComplete="onChildComplete(event)">
	</mx:Canvas>
	<mx:Canvas name="Child3" creationComplete="onChildComplete(event)">
	</mx:Canvas>
	<mx:Canvas name="Child4" creationComplete="onChildComplete(event)">
	</mx:Canvas>
</mx:ViewStack> 

Open in new window

0
 
dgofmanCommented:
You can use this MXML for UnitTesting :)


<s:layout>
	<s:VerticalLayout/>
</s:layout>
<s:NumericStepper id="ns" minimum="0" maximum="3"/>
<s:TextInput id="result" width="100%"/>
<mx:ViewStack id="mainView" width="100%" height="100%" creationPolicy="auto" initialize="init(event)" selectedIndex="{ns.value}">
	<mx:Canvas name="Child1" creationComplete="onChildComplete(event)" backgroundColor="#ff0000">
	</mx:Canvas>
	<mx:Canvas name="Child2" creationComplete="onChildComplete(event)" backgroundColor="#00ff00">
	</mx:Canvas>
	<mx:Canvas name="Child3" creationComplete="onChildComplete(event)" backgroundColor="#0000ff">
	</mx:Canvas>
	<mx:Canvas name="Child4" creationComplete="onChildComplete(event)" backgroundColor="#ff00ff">
	</mx:Canvas>
</mx:ViewStack> 

Open in new window

0
 
SreeramojuPradeepAuthor Commented:
Hi,

As per ur suggestion i dropped the idea of  using <s:NavigationContent>...

I am using just the canvas container...

I think since creation policy i set to "auto" we are using initalize="init(event)" for viewstack...
instead can we set the creation policy to "all" and omit the use of  initalize="init(event)" for viewstack...

And also i would like to use history management only for few childs of viewstack...
By default viewstack manages the history for all the child...can we overcome this...





0
Worried about phishing attacks?

90% of attacks start with a phish. It’s critical that IT admins and MSSPs have the right security in place to protect their end users from these phishing attacks. Check out our latest feature brief for tips and tricks to keep your employees off a hackers line!

 
dgofmanCommented:
I will recommend to use auto, and manager page creating from AS.
Don't forget the all will create all pages and if each page on initialize sending request to the server.
From your example you will fire at least 5 events on application loading.
For removing old child you can attach  "change" event listener ViewStack and using removeChildAt destroy last selected child
0
 
SreeramojuPradeepAuthor Commented:
I agree using auto...

U mean that using AS, we can instantiate only required child components & later others will be instantiated when selectedIndex is set to child component...

removeChild / removeChildAt is used to update the dispalyList...

But in my application i dont want to remove any child.. since the user can view any child component any time by clicking on carousel...

Since Viewstack has HistoryManagementEnabled...it holds the state of each child using history manager...

My issue is that only few child components should have the history management enabled within Viewstack....

Is there a way where we can reload the complete child page.....or change only few controls like combo box to its default state...

0
 
dgofmanCommented:
He, he..
Did you read documentation for historyManagementEnabled property?

    /**
     *  If <code>true</code>, enables history management
     *  within this ViewStack container.
     *  As the user navigates from one child to another,
     *  the browser remembers which children were visited.
     *  The user can then click the browser's Back and Forward buttons
     *  to move through this navigation history.
     *
     *  @default false
     */
    public function get historyManagementEnabled():Boolean

Is for Browser not for Flex Containers. Let me think how to help you
0
 
dgofmanCommented:
You gave me a good challenge!!!
After spent one hour looking Adobe Flex Container classes
and found only one solution :)

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
	
<fx:Script>
	<![CDATA[
		import mx.core.Container;
		import mx.events.IndexChangedEvent;

		protected function mainView_changeHandler(event:IndexChangedEvent):void
		{
			var vs:ViewStack = event.currentTarget as ViewStack;
			var child:Container = vs.getChildAt(event.oldIndex) as Container;
			if(child.childDescriptors != null){
				var n:int = child.childDescriptors.length;
				for (var i:int = n - 1; i >= 0; i--)
				{
					var component:DisplayObject = child.removeChildAt(i);
					var oldVisibility:Boolean = component.visible;
					component = vs.createComponentFromDescriptor(child.childDescriptors[i], false) as DisplayObject;
					component.visible = oldVisibility;
					child.addChild(component);
				}
			}
		}
	]]>
</fx:Script>
<s:layout>
	<s:VerticalLayout/>
</s:layout>
<s:NumericStepper id="ns" minimum="0" maximum="3"/>
<mx:ViewStack id="mainView" width="100%" height="100%" creationPolicy="all" selectedIndex="{ns.value}" change="mainView_changeHandler(event)">
	<mx:Canvas name="Child1" backgroundColor="#ff0000">
		<mx:ComboBox dataProvider="[1,2,3,4,5]" prompt="Select" x="10" y="40"/>
	</mx:Canvas>
	<mx:Canvas name="Child2" backgroundColor="#00ff00">
	</mx:Canvas>
	<mx:Canvas name="Child3" backgroundColor="#0000ff">
	</mx:Canvas>
	<mx:Canvas name="Child4" backgroundColor="#ff00ff">
	</mx:Canvas>
</mx:ViewStack> 
</s:Application> 

Open in new window


0
 
SreeramojuPradeepAuthor Commented:
Hi,

I implemented ur code...thats great man...Superb...increased the points..

Actually i wanted to make u clear that..
I am trying to implement the history management for desktop air application not for web application....

Is there any other way to use for desktop application for history management....

Let me know whether the history management is only for web application...
Then how abt the same in air application...

0
 
dgofmanCommented:
Forget about history management, its for Web Browser(s)
Working such this.
You are created your home page and implemented link to another page where Flex Application running.
When user press you this link browser reload your main.html file to next.html.
Now fon the Browser you will see "Back" arrow as enabled, if user will click on this button it will active "Forward" button. Now you have choice.
If user will press "Forward" button do you want to reload all children or not (historyManagementEnabled = true / false )
0
 
SreeramojuPradeepAuthor Commented:
Hi,
Yes i know history management is for browser....
Actually my need is...
My air application has many pages... on click of few buttons.. will be traversing b/w pages...
The user must have performed many actions in current page and click on a button and move to diiferent page i.e diiferent child of viewstack. When user again comes back to the current page on click of the button..the current page should show all the actions performed previously by the user...i.e the state of the page should be saved while traversing....

Suppose there is a Textinput control in a page name.mxml and user has entered his name..
TextInput --David
Once he click on a button move to diff page address.mxml  perform some action and comes back to
name.mxml page..at this point the value he is entered should remain ...
Like wise this is not only for textinput control...itapplies for container...child within containers and other controls..also

Saving state of each page can be achieved in air application....

0
 
dgofmanCommented:
Please use a Bindable Model design
You will able to handle any field changes / reset all files in one line / handle dirty type of your fields
You can use existing framework http://www.dremsus.com/index.php/tag/flex-binding/

or create a model class and declare [Bindable] meta tag on top
0
 
SreeramojuPradeepAuthor Commented:
I have a doubt...
In the below code snippet there is a ViewStack which contains many child components on click of buttons in each child i am moving b/w diff child components...
Assume their might be any num of controls or containers used within each child component of viewstack...
Once i move b/w child components the previous actions performed within each child remains as it is without any changes...some concept of state management is happening here...
Can u make me clear on this point....
 
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	<mx:ViewStack id="myVS">
		<mx:Canvas id="userName">
			<s:VGroup>
				<s:Label id="enterUN" text="UserName"/>
				<s:TextInput id="uN" />
				<s:Button label="Click Me" click="myVS.selectedIndex = 1"/>
			</s:VGroup>
		</mx:Canvas>
		<mx:Canvas id="address">
			<s:VGroup>
				<s:Label id="enteradd" text="Address"/>
				<s:TextInput id="addre" />
				<s:Button label="Click Me" click="myVS.selectedIndex = 2"/>
			</s:VGroup>
		</mx:Canvas>
		<mx:Canvas id="email">
			<s:VGroup>
				<s:Label id="enterEmail" text="Email"/>
				<s:TextInput />
				<s:Button label="Click Me" click="myVS.selectedIndex = 0"/>
			</s:VGroup>
		</mx:Canvas>
	</mx:ViewStack>
</s:WindowedApplication>

Open in new window

0
 
dgofmanCommented:
Here solution using bindable model

ViewModel.as
package
{
	[Bindable]
	public class ViewModel
	{
		public var textFieldValue:String = "";
	}
}

Open in new window


<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx">
	<fx:Script>
		<![CDATA[
			import mx.events.IndexChangedEvent;
			[Bindable] private var model:ViewModel;

			protected function changeHandler(event:IndexChangedEvent):void{
				model = new ViewModel();
			}
		]]>
	</fx:Script>
	<mx:ViewStack id="myVS" change="changeHandler(event)">
		<mx:Canvas id="userName">
			<s:VGroup>
				<s:Label id="enterUN" text="UserName"/>
				<s:TextInput id="uN" text="{model.textFieldValue}"/>
				<s:Button label="Click Me" click="myVS.selectedIndex = 1"/>
			</s:VGroup>
		</mx:Canvas>
		<mx:Canvas id="address">
			<s:VGroup>
				<s:Label id="enteradd" text="Address"/>
				<s:TextInput id="addre" text="{model.textFieldValue}"/>
				<s:Button label="Click Me" click="myVS.selectedIndex = 2"/>
			</s:VGroup>
		</mx:Canvas>
		<mx:Canvas id="email">
			<s:VGroup>
				<s:Label id="enterEmail" text="Email"/>
				<s:TextInput text="{model.textFieldValue}"/>
				<s:Button label="Click Me" click="myVS.selectedIndex = 0"/>
			</s:VGroup>
		</mx:Canvas>
	</mx:ViewStack>
</s:WindowedApplication> 

Open in new window

0
 
SreeramojuPradeepAuthor Commented:

I am clear with model binding...

u had told me that history management is not wrt containers it is wrt browsers....
I agree it is wrt browser...
But viewstack has that property i.e HistoryManagementEnabled =  true by default.
So while we are traversing b/w child components the previous actions performed (like opening documents within html component in flex i.e location does not change) by the user remains as it is
as user cums back to child again...
How is this state management happening.....
Is it due to what property of viewstack.....
Is it bec we are not reloading the child component again...i am confused pls make me clear on  this point...
0
 
SreeramojuPradeepAuthor Commented:
Also others containers like TabNavigator, Accordian also have this historyMangementEnabled property.......so what is the use of this
0
 
dgofmanCommented:
I don't know why HistoryManagementEnabled  in AIR applications, may be just deprecated option.
By can you tell me do you have still problem with Manager History implementation and what?
0
 
SreeramojuPradeepAuthor Commented:
No i am developing a air application so no need of history manager...

When moving b/w child components within Viewstack, Accordian or TabNavigator...
The previously performed actions remain as it is...so i just wanted to know how is this state mangement happening.....
0
 
dgofmanCommented:
HI SreeramojuPradeep,
Can you close this question? I think I gave you working solution
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

  • 10
  • 8
Tackle projects and never again get stuck behind a technical roadblock.
Join Now