reset the initial value of a observable

Hello everyone

I would like to find a way to restore the original state of a page each time it is invoked by a push of a navigation controller and consequently retain its status when I reactivate the page through the back.

To try to find a solution to this generic problem I make a concrete example on which I hope you can help me.

In the example (Look under) I have 3 pages. page1 recalls page 2. page2recalls page3.
page1 passes the name parameter to page2. page2 uses this parameter to initialize a observable.

My goal is to reset the value of this observable with its value that is passed from page1 every time I push the page2 from page1 but keep the value changed when I return from page3.

More generally I would like the content of a page to be reset to its original state whenever it is called up by a push.

I had thought about solving this problem in 2 different ways:

  1. Use the Reuse = "None" on the page 2. The problem though page 2 is recreated even when I go back from page 3. The ideal would be to keep instance of page2 when I do a goback from page3 and recreate it only when I push from page1. Looks like it’s not possible to do this. I also tried using the parameter Remove ="Released"but without success.

  2. Force this.Paramater.map to be invoked even when I pass the same data through the push. But even here it seems you can’t do it.

I hope someone can help me. Thank you

EXAMPLE COMPLETE:

<App>
	<Page ux:Class="Page1">
		<Router ux:Dependency="router" />
		<JavaScript>

		function OnClick(){
			router.push('page2',{name:'Giuseppe'});
		}
		module.exports={OnClick}
		</JavaScript>


		<StackPanel>
			<Text> Page 1</Text>
			<Button Clicked="{OnClick}" Text="go page2"></Button>
		</StackPanel>
	</Page>


	<Page ux:Class="Page2">
		<JavaScript>

		var Observable = require("FuseJS/Observable");

               //I want the observable derivative to be initialized with the value of the 
               //past parameter when the page is called from page1
		var name = this.Parameter.map(function(param){
			return param.name;
		})

		function OnClick(){
			router.push('page3');
		}
		module.exports={name,OnClick}
		</JavaScript>
		<Router ux:Dependency="router" />

		<StackPanel ItemSpacing="10">
			<Text> Page 2</Text>
			<TextInput Value="{name}"></TextInput>
			<Button Text="go Page 3" Clicked="{OnClick}"></Button>
			<Button Text="go back" Navigation="router">
				<Clicked>
					<GoBack/>
				</Clicked>
			</Button>
		</StackPanel>
	</Page>


	<Page ux:Class="Page3">
		<Router ux:Dependency="router" />

		<StackPanel>
			<Text> Page 3</Text>
			<Button Text="go back" Navigation="router">
				<Clicked>
					<GoBack/>
				</Clicked>
			</Button>
		</StackPanel>
	</Page>



	<Router ux:Name="router" />
	<Navigator DefaultPath="page1">
		<Page1 ux:Template="page1" router="router" />
		<Page2 ux:Template="page2" router="router" />
		<Page3 ux:Template="page3" router="router" />
	</Navigator>
</App>

If you only need to ensure that the parameter you pass to page 2 always changes, then you should do exactly that. As an example, here’s a classic trick you could use:

router.push("page2", {name: "Giuseppe", rand: btoa("p2" + Date.now())});

thank you for your suggestion! It’s works!

A curiosity, I get the same result if I send the converted timestamp to string instead of using the bto function. Can it be good anyway?

Sure, it just needs to be something that changes every time.

I also wanted to ask you if I can still instruct the navigator with the page creation / destruction strategy as outlined in my proposed solution? (this might be useful for other cases).

I don’t think there is a way to set Reuse so that it only dismisses pages when going in a particular direction.

A potential workaround would be to put the page3 as a child of page2, so that the instances of those are closely linked, but I’m not a fan of that idea.

All this is highly theoretical though. In a well designed app, you should not need to either forcefully remove pages, or force the change of a parameter when it didn’t change.

Thanks for your advice and I can agree with you not to destroy the pages but if a page is already instantiated and I want to reset a page to its original status I do not think it’s a problem with a bad design of the app. However if you have alternative solutions to advise me to better design this case I would be interested in listening to you. The use case is as follows as I think you have already imagined:

I have a form with different fields (which can be distributed on one or more cascaded pages) that the user can edit but until it saves the changes are not permanent. Therefore, if the user goes back, without saving them, and reloads the same the starting page, he must find the initial data.

Well based on the example code you provided, what I said was all there was to be said.

Your further explanation emphasises my point about bad design. If there is a dedicated “save” button, then your “currently editing a field” pages should work with a copy of data and only save to the source data in your model upon clicking that save button. If a user goes back without saving, the source will not have changed.

And if there is no dedicated “save” button, then the data should be saved in the source as it changes.

If this still doesn’t answer your question, I suggest you to make a complete, minimal reproduction of the actual challenge that you have, so that we aren’t talking pure theory, but instead solving something.

Thank you for your support.

I would like to make a clarification. When I go to the page I already copy a data (in fact, the data is passed as parameters within a push) and so I’m not going to change the data source that will only be changed when the user pushes the save button.

Anyway, I remembered that my use case is very similar to that of the Hike app tutorial and I noticed that to restore field values, he does this statements block:

function cancel() {
	// Refresh hike value to reset dependent Observables' values
	hike.value = hike.value;
	router.goBack();
}

I therefore seem to understand that the most correct approach to restoring the status of a page is when I make a back.

Uldis wrote:

Well based on the example code you provided, what I said was all there was to be said.

Your further explanation emphasises my point about bad design. If there is a dedicated “save” button, then your “currently editing a field” pages should work with a copy of data and only save to the source data in your model upon clicking that save button. If a user goes back without saving, the source will not have changed.

And if there is no dedicated “save” button, then the data should be saved in the source as it changes.

If this still doesn’t answer your question, I suggest you to make a complete, minimal reproduction of the actual challenge that you have, so that we aren’t talking pure theory, but instead solving something.

Anyway I do not see big differences if I force this.Parameter to update when I back up or when I push.
So when you talked about bad design, I wonder if the tutorial example also suffers from the same problem.

The tutorial / Hikr app is meant to explain the basic concepts used in Fuse. What works just fine there, does not necessarily mean it has to stay the same for larger, more complex applications.

So, to answer your question: no, Hikr does not suffer from the same problem, because it doesn’t try to do what you’re doing in your application.