Aurelia and ASP.NET 5 - Routing, Views, and Navigation, Oh My - Part 2
Brett M. Nelson - Friday, November 20, 2015
In Aurelia and ASP.NET 5 - Routing, Views, and Navigation, Oh My we added a new route to our application and the viewmodel and addition class we would need for our new view. Now lets add the required html.
Now We Need A View
Lets add an html file called comments.html to our app folder so we can have a matching view. Here we are going to put our <template> for the comments and it will look something like this:
<template>
If you have used Bootstrap before most of this should be familiar to you but I have annotated a few spots with a <!--Note: ####--> that should match up with one of the following explanations:
<!--Note: One-->: Here we usedvalue.bind="name"to use the data binding of Aurelia so that the value of this input is bound to the value ofnameon the view model. You can use.one-wayor.two-wayin place of the.bindto specify a certain binding type for your needs. It is also possible to use.one-timeto when you only want a value to populate in the view from the viewmodel during the initial binding phase.<!--Note: Two-->: This is the same binding syntax we used with the input for the name in<!--Note: One-->but its binding to the viewmodel'smessage.<!--Note: Three-->:Here we used theclick.trigger="addComment()to bind an event from the viewmodel to a trigger behavior. In this case the trigger behavior is a click and the event it causes to happen is theaddComment()method on our viewmodel.<!--Note: Four-->: This is the same event trigger binding syntax we used with<!--Note: Three-->but this time it binds to the viewmodel'sclearData()method.<!--Note: Five-->: Here we usedrepeat.for="comment of comments"to iterate over our viewmodel's collection of Comments. The element therepeat.foris on acts as the root element for the repeat. The root element could have multiple html child elements or none at all.<!--Note: Six-->: Here we use the string interpolation syntax to do one way binding of the current comments name.<!--Note: Seven-->: Similar to<!--Note: Six-->here we use the string interpolation syntax to do one way binding of the current comments message.<!--Note: Eight-->: Here we usedclick.delegate="deleteComment(comment)", this is similar to theclick.triggerwe used in<!--Note: Three-->the difference between thetriggeranddelegateis that atriggeris bound directly to the element while adelegateis bound to the document once and and reused. This means that you can bind to the delegate multiple times without affecting performance.
I added deleteComment(comment) method to the
comments.jsclass we discussed last time. It looks like this:deleteComment(comment){ for(let i = 0, m = this.comments.length; i < m; i++ ){ if(this.comments[i].name === comment.name && this.comments[i].message === comment.message){ this.comments.splice(i, 1); return; } } }
Now if we run our app and go to our new view at `/index.html#/comments`, in my case that means `http://localhost:8339/index.html#/comments`, and we should see our little form with two text boxes and two buttons. Why not try and add a few comments.
##### Comments in Action

Now that we have that working maybe we should do something about that navigation issue.
When last we looked at our `app.html` it looked a little sparse.
##### Original `app.html`
```html
<template>
<router-view></router-view>
</template>
So we will need to build this out some so that we are generating our navigation menu based on routes provided when we mapped routes in our app.js. In our app.js we also stored a reference to our router so we could use it later. Well now is later so lets get to modifying our app.html.
<template>
<nav class="navbar">
<ul class="nav nav-tabs">
<li
repeat.for="row of router.navigation"
class="${row.isActive ? 'active' : ''}"
>
<!--Note: One-->
<a href.bind="row.href">${row.title}</a
><!--Note: Two-->
</li>
</ul>
</nav>
<router-view></router-view>
</template>
<!--Note: One-->: We have a few things going on in this line. We start with arepeat.forlike we used before but this time we are iterating over our navigation collection on the router. We also are using some basic logic syntax to inside the string interpolation binding to determine if we should add theactiveBootstrap class.<!--Note: Two-->: There are a few things going on here as well. First we use the.bindsyntax again to bind the href to the rows href. Second we use the string interpolation again to bind the rows title.
Now when we run our app we should have a navigation menu at the top of the screen we can use instead of having to enter in the view we want to visit manually.
Navigation in Action

And with that we have a very simple Single Page Application that uses Aurelia. I hope this helps you get started. If you have any questions though feel free to leave a comment or send an email to [email protected] and I'll see how I can help.