简体   繁体   English

如何在Aurelia中的路线之间重用数据?

[英]How to reuse data between routes in Aurelia?

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: 我有以下要求:

  1. Edit form should have a separate URL address, so it can be sent to others easily. 编辑表单应具有单独的URL地址,以便可以轻松将其发送给其他人。
  2. When user clicks the Edit button on the user's details page, the edit form should use an already loaded instance of the user (ie it should not contact the API again for user details). 当用户单击用户详细信息页面上的“ 编辑”按钮时,编辑表单应使用已加载的用户实例(即,它不应再次与API联系以获取用户详细信息)。
  3. When user clicks the Edit button on the user's details page and then the Back button in the browser, he should see the details page without edit form again. 当用户单击用户详细信息页面上的“ 编辑”按钮,然后单击浏览器中的“ 后退”按钮时,他应该再次看到没有编辑表单的详细信息页面。

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. 这满足了#1和#3的要求,但是在打开编辑表单时必须再次加载用户。

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 (eg user accesses the URL directly). 如果我可以将预加载的用户实例传递到编辑路径,而编辑组件将使用它,或者在未提供该实例的情况下加载一个新实例(例如,用户直接访问URL),那将是完美的。 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. 我决定以模式显示编辑表单,并在有?action=edit GET参数时自动显示它。 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). 这将传递#1(编辑URL为user/123?action=edit )和#2(用户实例仅加载一次)。 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). 但是,当用户单击“ 后退”浏览器按钮时,URL会根据需要从user/123?action=edituser/123但是我不知道如何检测到它并隐藏编辑表单(不会再次调用activate方法) 。 Therefore, this solution fails the #3 requirement. 因此,此解决方案无法满足#3要求。

EDIT: 编辑:

In fact, I have found that I can detect the URL change and hide the edit form with event aggregator: 实际上,我发现我可以检测到URL更改并使用事件聚合器隐藏编辑表单:

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? 如何以一种干净直观的方式应对这种情况?

How about adding a User class that will serve as the model and use dependency injection to use it in your view-models? 如何添加将用作模型的User类,并使用依赖项注入在视图模型中使用它?

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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM