How do I navigate between two pages while passing and updating data?


#1

Hello,

I started learning {N} about a week ago. I have read the “The NativeScript Book” PDF (up until chapter 8 that covers most of the basics); I have went through the getting started tutorial in the docs; I have been going back and forth between the docs and the API docs; I have looked at online code samples; I have installed and looked at the master-detail template. So far I have not seen a SIMPLE WORKING code example that correctly demonstrates the use of using two simple pages passing and modifying data between the two, using JS and XML.

Most code sample show how to pass data to Page 2 and it stops there. There is a sample in the PDF book “The NativeScript Book” on how to do this, but the code doesn’t work and it crashes. The Firebase template doesn’t work because you have to tinker with Firebase and its setup in order to enable editing in the template and I’m not familiar with Firebase.

This is what I’m looking for…

  1. Setup 2 pages using JS and XML.
  2. Page 1 will display an ActionBar with the title of the page and the page content will show some data (eg a label).
  3. Have a button on Page 1 (eg Edit). When you tap this button, it will go to Page 2, transferring the data from Page 1. Let’s say this data shows up on Page 2 in a textfield.
  4. At this point, because you used frame.topmost().navigate(), on Page 2 the “< Back” button will automatically show up in the ActionBar. When you tap this Back button, the page automatically goes back to Page 1, by design, without modifying the data. So far so good.
  5. However, if you change the data on Page 2 (eg you type a string into the textfield) and you press “Done” indicating that you want to commit your changes, you call frame.topmost().navigate() to navigate back to Page 1, transferring the modified data.
  6. When you navigate back to Page 1, by default the page will slide towards the LEFT - which is incorrect! If you do this, the page you will navigate to will also have a “< Back” button in the ActionBar, so you did NOT navigated back (technically) to Page 1.
  7. In order to remedy this, you just change the transition type so the page will slide towards the RIGHT. However, in this case, when you are on Page 2, the page will indeed slide towards the RIGHT, but the “< Back” button in the ActionBar will slide towards the LEFT!!! So you will see that the bottom (content) part of the page is sliding one way, and the top (ActionBar) part slides the opposite way. This is not correct!

This is a very simple example, yet I can’t find one that executes it (and works) correctly. Can anyone points me to a simple example that works and illustrates this concept?

Thanks.


#2

to make the template works without firebase, you basically uncomment this code block

and comment this block

however, now In order to make the changes to the item persist, then you will be needing to use a database like SQLite or Couchbase (or use local file system) to store your changes, and in this case you will need to overwrite saveChanges function to adapt it to the saving method you chose


#3

Here’s my problem. I wanted to find a SIMPLE example that illustrates the concept of

  1. Having some data on Page 1 (eg a label with a text) and a button “Edit”.
  2. When I tap “Edit” I go to Page 2.
  3. On Page 2 there’s a textfield with the text of the label passed from Page 1.
  4. There’s a button “Update” below the text field.
  5. When I change the text in the textfield and press “Update”, I go back to Page 1 and the label text will update with the text that was transferred from Page 2. However, when I press the “< Back” button in the ActionBar, I still go back to Page 1, but the data will NOT be updated.

Here is why I am struggling with this for 3 days now.

  1. When you press the “< Back” button in the ActionBar and you go back to Page 1, you use Frame.topmost().goBack(). This will NOT modify the data on Page 1. Which is good.
  2. However, when I press the “Update” button on Page 2, you cannot use Frame.topmost().goBack() because that will not transfer navigationContext back to Page 1. You also cannot use Frame.topmost().navigate() because that will navigate the opposite direction (I have already pointed this out in my original question above.

When you use Frame.topmost().navigate() it is using a transition that animates the page by sliding it towards the LEFT.

In order to navigate back, you have to use the opposite transition, to slide RIGHT. When you do this, the page will slide correctly towards the right, but the ActionBar will slide towards the LEFT. This is incorrect!!!

The master-detail example doesn’t use this transition. They use slide DOWN and slide UP.

So the question still remains. How do you navigate between Page 1 and Page 2 by passing a data to Page 2, modify it, and pass it back to Page 1 ONLY if you tap the “Update” button? (All this with the correct sliding left/right animation in both the page AND the ActionBar.)


#4

Well, this is how I solved it. I don’t know if this is considered a “good” solution, but it does seem to work.

When I want to go back to Page 1 after tapping the “Update” button (as opposed to using the “< Back” button in the ActionBar), I get the backStack (using Frame.topmost().backStack) and modify its entry property (which is a NavigationContext). This way, when I go back to the previous page (Page 1), the navigation context will be set correctly and can be used as the binding context for Page 1.

exports.onTapUpdate = function(args) {
	// Get the Page object
	let object = args.object;

	// Get the backStack of the Frame
	let backStack = Frame.topmost().backStack;

	// Modify the 'entry' property (which is a NavigationContext),
	// in order to set it as the binding context of the page we
	// are returning to. 'message' is the string that is entered/modified in the TextField.
	backStack[backStack.length - 1].entry = {
		context: {
			message: object.bindingContext.message
		}
	};

	// Go back to the previous page.
	Frame.topmost().goBack();
}

If anyone knows a better solution, please do let me know! (thanks in advance)