Aurelia - переключение между корнями приложений с различными конфигурациями маршрутов

ОБНОВИТЬ

Может ли эта проблема иметь какое-то отношение к проблеме мю? https://github.com/aurelia/framework/issues/400


У меня есть приложение Aurelia с двумя разными корнями, одно для входа пользователей, а другое для анонимных пользователей.

В других приложениях Aurelia я реализовал изменение корня приложения на основе подхода, приведенного в этом ответе. Это очень хорошо работает, когда login Модуль является "изолированным" модулем без дополнительных маршрутов, но сейчас мне трудно заставить его работать.

index.js - root для анонимных пользователей

import {inject, useView, Aurelia} from "aurelia-framework";
import AuthService from "./services/auth-service";

@useView("app.html")
@inject(AuthService)
export class Index {   
    constructor(authService) {
        this.auth = authService;
    }

    configureRouter(config, router) {
        config.title = "Super Secret Project";
        config.options.pushState = true;
        config.map([
            { route: ["","home"], moduleId: "home", nav: true, title: "Beginscherm" },
            { route: "over", moduleId: "about", nav: true, title: "Over" },
            { route: "inloggen", moduleId: "account/login", nav: false, title: "Inloggen" }
        ]);

        this.router = router;        
    }
}

ic-app.js - root для авторизованных пользователей

import {useView, inject} from "aurelia-framework";
import {RequestStatusService} from "./services/request-status-service";
import AuthService from "./services/auth-service";

@useView("app.html")
@inject(RequestStatusService, AuthService)
export class App {
    constructor(requestStatusService, authService) {
        this.requestStatusService = requestStatusService;
        this.auth = authService; // we use it to bind it to the nav-bar-top
    }

    configureRouter(config, router) {
        config.title = "Super Secret Project";
        config.options.pushState = true;
        config.map([
            { route: ["", "selecteer-school"], moduleId: "ic/select-school", nav: false, title: "Selecteer School" },
            { route: "dashboard", moduleId: "ic/dashboard", nav: true, title: "Beginscherm" },
        ]);

        this.router = router;
    }
}

код входа в систему на auth-service.js

logIn(userData, rememberMe = false) {
    this.requestStatusService.isRequesting = true;
    return this.http
        .fetch("/token", { method: "POST", body: userData })
        .then((response) => response.json())
        .then(response => {
            if (response.access_token) {
                this.setAccessToken(response.access_token, response.userName, rememberMe);
                this.app.setRoot("ic-app");
            }
        });
}

а также...

код выхода из системы в auth-service.js

logOff() {
    AuthService.clearAccessToken();
    this.app.setRoot("index");
}

Эта проблема

Установка различных корней приложения работает, как и ожидалось, проблема в том, что я ожидаю, что новый корень приложения автоматически перейдет к маршруту по умолчанию для нового корня, хотя он пытается загрузить маршрут, которым он был в данный момент. setRoot(...) называется.

Для иллюстрации на примере

  1. Я на странице входа. current route: /inloggen
  2. Я нажимаю кнопку входа в систему. app.setRoot("ic-app") is called
  3. Новый корень загружен; configureRouter в ic-app.js вызывается, а потом...
  4. Ошибка консоли: Route not found: /inloggen

Новый корень пытается остаться в том же /inloggen маршрут, но я бы хотел, чтобы он загружал маршрут по умолчанию для этого корня приложения или переходил к нему. То же самое происходит при выходе из системы.

Как заставить приложение перейти на маршрут по умолчанию после изменения root?

3 ответа

Я получил это работает отлично, я ответил больше о том, как в этом потоке stackru:

Aurelia очищает историю маршрутов при переключении на другое приложение с помощью setRoot

В основном сделайте следующее

this.router.navigate('/', { replace: true, trigger: false });
this.router.reset();
this.router.deactivate();

this.aurelia.setRoot('app');

В роутере для анонимных пользователей используйте mapUnknownRoutes, Как это:

configureRouter(config, router) {
    config.title = "Super Secret Project";
    config.options.pushState = true;
    config.map([
        { route: ["","home"], moduleId: "home", nav: true, title: "Beginscherm" },
        { route: "over", moduleId: "about", nav: true, title: "Over" },
        { route: "inloggen", moduleId: "account/login", nav: false, title: "Inloggen" }
    ]);

     config.mapUnknownRoutes(instruction => {
       //check instruction.fragment
       //return moduleId
       return 'account/login'; //or home
     });

    this.router = router;        
}

Сделайте ту же стратегию в другом маршрутизаторе. Теперь попробуйте выйти из системы и войти снова, вы увидите, что пользователь будет перенаправлен на свой последний экран.

РЕДАКТИРОВАТЬ

Другое решение - перенаправление на нужный маршрут после установки rootComponent. Например:

logOut() {
   this.aurelia.setRoot('./app')
    .then((aurelia) => {
      aurelia.root.viewModel.router.navigateToRoute('login');
    }); 
}

Вот работающий пример https://gist.run/?id=323b64c7424f7bec9bda02fe2778f7fc

Моя лучшая практика - просто направить их туда, и это то, что я делаю в своих приложениях:

login(username, password) {
  this.auth.login(username, password)
    .then(() => {
      this.aurelia.setRoot('app');
      location.hash = '#/';
    });
}
Другие вопросы по тегам