• Overview
  • Transcript

3.2 Navigate Between Pages

Navigation on the web uses hyperlinks. We can use them in our app, but it’s better to rely upon WinJS’s navigational capabilities, along with a navigator control that Microsoft wrote. In this lesson, I’ll show you some limitations of hyperlinks in Windows 10 apps, and I’ll show you how to use the more robust alternatives.

Related Links

3.2 Navigate Between Pages

In traditional web pages, we use a hyperlink to navigate from one page to another. And we can do that within our application. However, we don't really want to. And I will show you why, and I will also show you what we should be doing. So let's first of all add a new page to our application. Now I'm going to do this in a very verbose way. Now if you look at the samples that Microsoft has given us, and I will give you a link to the GitHub repository where those samples are, they have organized their applications so that your main page is at the root of your project. And then all the other pages that you might need within your application are within in a folder called pages. And then inside of this pages folder are going to be more folders for each individual page. So for example, we are going to create a subscriptions page, something that we can use to set our subscriptions that we want to display within our application. So I'm creating a folder called subscriptions inside of pages. And then inside of this folder we would have the HTML file, so let's go ahead and create that. And any supporting assets that are needed for subscriptions would also be within this subscriptions folder. Now if there were something that was needed across the entire project, then it would go inside of the js folder or the images or css. But the things specific for subscriptions would be localized inside of this subscriptions folder. But for right now we're just going to stick with this HTML file. We will add some JavaScript later on. So let's go back to our default HTML, and let's add just a simple hyperlink. So we want the href to be set to pages/subscriptions/subscriptions.html, and go to subscriptions. So let's run this and let's see what happens. Now you've probably already guessed that whenever you click on this link, it's going to take you to the subscriptions page, and that is indeed what it does. But we also lose all of our UI. Now that is to be expected, because the page that we just created, subscriptions.html, is completely blank. And of course, if we put something in here, then we would have seen it, although why we didn't see Content goes here I don't know. But that's the problem when it comes to using hyperlinks within our application. Instead, we want this to be more like a single-page application so that our default page is the main page. And then we define an area within this page that's going to display the content, so that the UI stays the same but the content changes. And we are going to do that, but we are going to rely upon a component that Microsoft has written, but they haven't included it within this template. In fact, this component was used in prior versions of HTML applications for Windows 8 and 8.1. And it's not part of WinJS, and I wish it was. But instead, if we wanted to use it within those Windows 8 and 8.1 applications, we had to create a project that already had the navigation built in. And it used this component called PageControlNavigator. Now this particular version is one that I took from the samples that Microsoft has provided. So as far as I'm aware, this has been updated for WinJS 4, although it might be the exact same version that you will find in Windows 8 and 8.1 applications. Now one of the wonderful thing about these HTML applications is that they have JavaScript. And we can go in and we can modify the JavaScript as we need, and we will be doing that here for this PageControlNavigator in a few moments. But first I want to point out the use of this, WinJS.Namespace.define. Now we know that JavaScript doesn't have namespaces, but they can be emulated with using objects. And that is essentially what's being done here. You know in C#, Visual Basic, .NET, and all of those other languages, you have namespaces. So that is what is being emulated here for our JavaScript. So whenever we want to access this PageControlNavigator class, then we have to say application.PageControlNavigator. And I will show you that right here, because we are going to go ahead and add that control. So there are two pieces here. We need this PageControlNavigator, but we're also going to use the navigation capabilities in WinJS. So the first thing we need to do is add that PageControlNavigator. So we will do that with a div element. Although first of all we need to add that JavaScript file here. So let's add script src and that is in the js folder, navigator.js, so we have a reference to that now. And inside of this div element we are going to give it an id. Let's say contenthost, and then we want data-win-control. Now here we say that this is application.PageControlNavigator. This is not part of WinJS, this is a separate component. And just like all of the other controls, there are some options that we can go ahead and set. Now one of those is a home page, and we don't have a home page just yet. Well, we kind of do with default HTML, but that's not going to be our home page as far as the content is concerned. Instead we are going to say subscriptions. And we are going to set that to the URL of our page so that is /pages/subscriptions/subscriptions.html. Now this subscriptions option actually isn't part of this PageControlNavigator. This is something that we will have to add to that class. But since this is JavaScript, we can do that very easily. So these options is an object literal that is going to be passed to the constructor of the PageControlNavigator. So you have the element which is being passed, that is that div element, and then there are the options, that is the content of our options attribute. So you can see here that there is an option called home, and that is being assigned to a home property. Well, we are going to do the same thing for subscriptions. So we are going to take the option that is for subscriptions and assign that to the subscriptions property. Now the reason why we're doing it this way is so that we are setting it once here and we no longer have to refer to the actual URL. We will be able to use this subscriptions property, and that will come in handy later on. So we change this line of code, or we add it, rather. I had it commented out because I have already done this, and there's one other place. The constructor for PageControlNavigator. You can see that it's using WinJS.Class.define, so this is defining a class, but it's not using anything from ECMAScript 2015, as far as the classes are concerned. And that's because at the time that all of this was written, classes didn't exist. So this is the next best thing, where you have a constructor, and then after the constructor you have the properties of that particular object. So here you can see home. It is initialized as an empty string, going to do the same thing with subscriptions. So you could do the same thing with any other pages that you wanted within your applications. If you're using this PageControlNavigator, then you can come in here and you can set the value of these properties once so that you don't have to do it again. And then you can just refer to the properties itself to go to those places. So we have our content host where all of our content is going to be loaded whenever we navigate to a page. Now we just need to navigate. Whenever we click on either the home command, or the subscriptions command we want to navigate. Now these are commands. These aren't links or anything like that. So you don't click a command, even though that's what we do. Instead, you invoke a command. So we don't have a click event, it's called oninvoked. And then we specify the code that we want to execute. Now we don't have this code yet, but we are going to write that. Now I'm going to put all of this code inside of a namespace called DefaultPage, because we don't want these event handlers to just be in the global namespace. We haven't been doing that for years in normal JavaScript applications. So we're going to group everything inside of the namespace in order to protect ourselves from naming conflicts and all of that other stuff. So we're going to have DefaultPage.subscriptionsClicked. So let's go to our default.js file, and we are going to write that code. The first thing we need is our namespace. And we're going to do the same thing that was done really inside of this navigator file where we have WinJS.Namespace.define. So WinJS.Namespace.define, the first argument to this function is the name of our namespace, so DefaultPage. And then the second argument is an object that contains everything that's going to be within this namespace. So if it was a class, it would have the class name here, any properties that we might want to make available or methods, you know those types of things. In our case we have some event handlers. So that is going to be subscriptionsClicked. Now unfortunately, this isn't just a normal function. Instead we have to create an event handler. That is when WinJS.UI.eventHandler. But this is going to wrap around a normal function, so at least now we're in normal territory. So we have our event handler. We are passing it the function that it's going to execute. And really all we want to do is navigate to our subscriptions page. Well, we do that with WinJS. There is a Navigation namespace, and it has a method called navigate, and we tell it where we want to navigate to. Now in this case, we want to navigate to our subscriptions page. Now we could type in that URL, but we don't have to, because remember we have that as a property for our navigation control. Now if we go to our PageControlNavigator, if we scroll all the way down to the last line of the constructor, you can see that Application.navigator = this. So this is essential a singleton, and Application.navigator is what we would use in order to access that subscriptions property. So we would have Application.navigator.subscriptions, and that will take us to our subscriptions page. Now WinJS.navigation, this is something that we would use fairly often. So we could make a variable that will give us a shortcut there, so let's go ahead and do that. Let's say var nav = WinJS.navigation, and then we can just say nav.navigate, and then we navigate to the subscriptions page. So before we run, let's just go to subscriptions and let's change this so that it's obvious. Let's say that This is the subscriptions page, so that we know with a doubt that that is what's going on. Let's run this app. Whenever we click on the subscriptions command, there we go. This is the subscriptions page. If we click on home, nothing happens. First of all because we haven't set up that on evoked event, and we also don't have a home either. So let's go ahead and let's create that. We're going to do the same thing that we did for subscriptions, except that we are going to call this news. So the news page is going to be our home page. Let's add an HTML file called news.html. And let's say that This is home. And then inside of default HTML where we set the options for our navigator, we are going to say home is our /pages/news/news.html. We want to handle that oninvoked event for our home command, so let's just copy and paste. We'll change the name to homeClicked, and then we will add that code. So we'll go to default.js. Let's just copy what we have for subscriptions clicked, and we will paste it. Let's change the name to homeClicked, and then the URL is .home. So whenever we run this now, we aren't going to go straight to home yet. We need to tell our app that we are going to do that. So whenever we click on home, we see that this is home. Whenever we click on subscriptions, this is the subscriptions page. Now notice that we have a back button now. If we click on the back, it takes us to home. So this is where that page control navigation comes into play. Now that we have a home, we have a place that's always home and we can always go back to it. But notice now, whenever we go to subscriptions, we click on home again, we still have a back button. Wouldn't it be nice if we just cleared the history so that whenever we are home there's no more going back. Cuz even clicking home multiple times, you know that's gonna take us back to home. So let's change that, and we can do that very easily. Whenever we click on home, we just want to clear out the back stack and the forward stack for our history. We do that as part of WinJS.Navigation. So we're going to say nav.history.backStack. This is just an array that we are going to set to an empty array. We'll do the same thing for the forwardStack, and that will clear the history. So every time we go back to home, then our history is cleared, because really there's really no other place to go back to. But we also want our application to automatically go home whenever it opens. And we can do that here, whenever this WinJS.UI.processAll() is executed, because remember, this is executing when our application is launched. So after the UI is processed, that is when WinJS is going to go through all of our HTML and create all of our controls and do everything that it needs to do for those controls. After that's done, then we want to navigate to our home. So we will say .done after we processAll. And then here we are going to navigate with nav.navigate, and we are going to go to Application.navigator.home. So now whenever we run this application, it's going to automatically take us to home, and then that's going to be our starting point. There it goes. Let's go ahead and make that smaller. Whenever we go to our subscriptions, we see that. We have our back button. And if we go back, we go back to home. But if we click on home it's also going to clear out our history. So there's no place to go back to, because really we only have one other place to go, and that is to the subscriptions page. Well, now that we have page navigation working, we need to actually have something within our pages. To me, the most obvious place to start is in the subscriptions page, because we need to be able to set whatever RSS or Atom feed that we want to read. So that's what we are going to do in the next lesson. We will create that form. We will also store that information so that it will be saved not only on the current device but across all of our other devices.

Back to the top