Open jwx opened 5 years ago
@jwx This is really nice. I like the simplicity of viewports for rendering components in this way. Easy to understand and just as powerful as the previous routing solution.
I should probably point out that the separators, @ and = (and the others that exist but aren't shown in these examples), isn't locked in. And that the plan is also to have them configurable so that developers can get a syntax they like.
Probably the part that gives uneasy feeling about this is the mental model mapping of URL to viewport.
authors/about
# invoices/:id/items
invoices/1fdsf324-113n3-df314-1313123123/items
The first url can be explained into viewport quite comfortably. How should I think about the second one in this model? Apologize if explained elsewhere, I haven't followed closely.
It's good that you haven't followed closely since it results in the kind of questions I want. Your question would've been answered in the next step of the instruction, but I haven't written it yet. Briefly, how you should think is "the component InvoiceItems
wants an id
parameter", meaning
invoice-items=1fdsf324-113n3-df314-1313123123
Routing
Navigation in Aurelia is handled by viewports and components. In short, you put one or more viewports in your application and then you specify their content using links or code. Whenever someone navigates to a new state of viewport components an entry will be added to the browser history, making it possible to use the browser's back, forward and refresh and get the right set of components. Let's take a look at an example.
Viewports
For the start view of our app, we're going to use two viewports:
The first viewport we'll give the name lists and specify that it's only used by the components/custom elements Authors and Books. We also set Authors as the default component, meaning that if nothing is specifically set for this viewport, it will display the Authors component. For the second viewport we won't specify anything except giving it the name content and setting the default to the About component. Convention will then allow all components not used by another viewport to use it. Note: While it's not necessary to explicitly name a viewport (it will then be named default by convention), it is recommended. Especially if you have more than one viewport in your application.
That's it for setting up the viewports. Now let's look at how to navigate and change the components in them.
Navigation
Navigation can be triggered in html through
a
nchor tags or in code with the router'sgoto
method. (There are more navigation methods available in the router, but we'll stick togoto
for now.) A navigation segment in it's basic form consists of three parts: which component to show, in which viewport to show the component and what parameters to pass into the component, like thisor this
But sometimes you don't want to pass parameters to the component, so that part is optional. And if the router can deduce where a component should go by itself, for example based on the viewport settings we did earlier, viewport can also be left out. So if you're using only one viewport, or have done a configuration similar to the one we did, you don't have to think about the viewport when navigating. Our
nav
part from above could then beWhat's happening here then? The
about
is easy enough to understand, but what's the+about
part afterauthors
andbooks
? Well, a navigation instruction can consists of several navigation segments, separated by+
, meaning that we can change the components in more than one viewport in the same navigation instruction. Theauthors+about
instruction is in its full formauthors@lists+about@default
, but since bothauthors
andbooks
are used by thelists
viewport we don't have to specify viewport name for them. And since those two are the only components that can use thelists
viewport, all other components, includingabout
, has nowhere to go but thedefault
viewport so we don't have to specify viewport for them either.And that's it! We've now set up our main application navigation.
Parameters
Quite often you'll want to pass parameters when navigating to a component. In our example, the lists viewport might show the
Books
component which displays a list of books and if someone clicks on the title of a book, we want to display details about that book in our content viewport.So we'll have the
Books
component fetch a list ofbooks
from somewhere and then display it with thiswhich could result in
The
href
attribute contains the navigation instruction and basically says "show theBook
component where book is1
". Since the lists viewport is only available for theAuthors
andBooks
components, theBook
component will be loaded into the only remaining viewport, content. When the router loads theBook
component it will call a method calledenter
in it. This method will receive the parameter(s) specified in thehref
in a list as the first argument.Named parameters
If we're not fond of unnamed parameters in a list, there's a simple way to get them named: add the name to the parameters in the
href
The first parameter to the
enter
method would now be an object:It's also possible to pass more than one parameter to the
enter
method.Now, however, our
href
s are getting a bit verbose due to the names. Fortunately, there'a another way to specify the parameter names: add a static property calledparameters
to the component:The
href
is now shortened toMost of the cases, though, you'll probably only pass one parameter, some kind of
id
, so that thehref
will read "show component where [component name] is [id value]".That's it for navigating around and passing parameters between components!
Next we'll look into something that's a lot easier than it sounds: having components with their own viewports!