There seems to be some confusion about what Router#navigate
does exactly, I think.
Without any options set it will update the URL to the fragment provided.
E.g. router.navigate('todo/4/edit')
will update the URL to #todo/4
AND will create a browser history entry for that URL. No route handlers are run.
However, setting trigger:true
will update the URL, but it will also run the handler that was specified for that route (In Addy's example it will call the routers editTodo
function) and create a browser history entry.
When passing replace:true
the url will be updated, no handler will be called, but it will NOT create a browser history entry.
Then, what I think the answer is:
the reason why the usage of trigger:true
is discouraged is simple, navigating from application state to application state to application state requires most of the time different code to be run than when navigating to a specific application state directly.
Let's say you have states A, B and C in your application. But state B builds upon state A and state C builds upon B.
In that case when you navigate from B to C only a specific part of code will need to be executed, while when hitting state C directly will probably execute some state checking and preparation:
- has that data been loaded? If not, load it.
- is the user logged in? If not redirect.
etc.
Let's take an example: State A (#list
) shows a list of songs. State B (#login
) is about user authentication and state C (#list/edit
) allows for editing of the list of songs.
So, when the user lands on state A the list of songs is loaded and stored in a collection. He clicks on a login-button and is redirected to a login form. He successfully authenticates and is redirected back to the song list, but this time with delete-buttons next to the songs.
He bookmarks the last state (#list/edit
).
Now, what needs to happen when the user clicks on the bookmark a few days later?
The application needs to load the songs, needs to verify the user is (still) logged in and react accordingly, stuff that in the state transition flow had already been done in the other states.
Now for a note of my own:
I'd never recommend the above approach in a real application as in the example. You should check whether the collection is loaded when going from B to C and not just assume it already is. Likewise you should check whether the user really is logged in. It's just an example.
IMO the router really is a special kind of view (think about it, it displays application state and translates user input into application state/events) and should always be treated as such. You should never ever rely on the router to transition between states, but rather let the router reflect the state transitions.