I think it's a "copy by val vs copy by ref" scenario...
I added a couple of blocks in index.html to see more details ($routeParams, $routeParams.bookId, bookId and $bookId with and without the main. prefix
Also, in script.js, within MainCntl, I added this.$bookId
I'm not sure if any of these are the lines that troubled you to begin with.
One possibly surprising aspect is that the MainCtrl is not re-run when you go from one "page" to the other.
In fact, angular routing refreshes only the block of HTML marked as the view (<div ng-view class="view-animate"></div> in this case),
and the blocks showing the output values are all outside of that container (but within the one using MainCntl as controller: <div ng-controller="MainCntl as main">)
So, maybe the question should be why do we see some of these values being updated?
The line in scripts.js (MainCntl): this.$routeParams = $routeParams
makes this.$routeParams as a pointer to the $routeParams object that angular updates when we click onto a book/chapter link
While: this.bookId = $routeParams.bookId;
makes a value copy (the current value of $routeParams.bookId is copied and stored into this.bookId)
So, if our HTML template has a binding ref to the variable in the former case (this.$routeParams), the angular 2-way binding will tell us when it is updated.
That's true in the latter case as well, but because we grabbed a copy of the $routeParams.bookId value when running through MainCntl the first time, we are not being told when $routeParams is updated through successive clicks/navigation
Why the difference? If I'm not mistaken the answer would come from JavaScript rather than angular knowledge.
I know, someone will correct me if I'm wrong, but at least they'll enlighten me too!
HTH,
F