Reputation: 21249
I have an user entity in the system and the following route fetches it from server and displays its details:
routerConfiguration.map([
// ...
{route: 'user/:id', name: 'user-details', moduleId: './user-details'}
]);
Now I want to display an edit form for the displayed user. I have the following requirements:
1st attempt
I tried to define the edit form as a separate page:
routerConfiguration.map([
// ...
{route: 'user/:id/edit', name: 'user-edit', moduleId: './user-edit'}
]);
This passes the #1 and #3 requirement but it has to load the user again when the edit form is opened.
I don't know any way to smuggle some custom data between the routes. It would be perfect if I could pass the preloaded user instance to the edit route and the edit component would use it or load a new one if it is not given (e.g. user accesses the URL directly). I have only found how to pass strings to the routes in a slighlty hacky way.
2nd attempt
I decided to display the edit form in a modal and show it automatically when there is a ?action=edit
GET parameter. The code inspired by this and this question:
export class UserDetails {
// constructor
activate(params, routeConfig) {
this.user = /* fetch user */;
this.editModalVisible = params.action == 'edit';
}
}
and when the user clicks the Edit button, the following code is executed:
displayEditForm() {
this.router.navigateToRoute('user/details', {id: this.user.id, action: 'edit'});
this.editModalVisible = true;
}
This passes #1 (the edit url is user/123?action=edit
) and #2 (the user instance is loaded only once). However, when user clicks the Back browser button, the URL changes as desired from user/123?action=edit
to user/123
but I have no idea how to detect it and hide the edit form (the activate
method is not called again). Therefore, this solution fails the #3 requirement.
EDIT:
In fact, I have found that I can detect the URL change and hide the edit form with event aggregator:
ea.subscribe("router:navigation:success",
(event) => this.editModalVisible = event.instruction.queryParams.action == 'edit');
But still, I want to know if there is a better way to achieve this.
The question is
How to cope with this situation in a clean and intuitive way?
Upvotes: 5
Views: 472
Reputation: 2175
How about adding a User class that will serve as the model and use dependency injection to use it in your view-models?
export class User {
currentUserId = 0;
userData = null;
retrieve(userId) {
if (userId !== this.currentUserId) {
retrieve the user data from the server;
place it into this.userData;
}
return this.userData;
}
}
Upvotes: 3