Aurelia - Switching between app roots with different route configurations

痴心易碎 提交于 2019-12-12 10:37:35

问题


UPDATE

Could this issue have something to do with mu problem? https://github.com/aurelia/framework/issues/400


I have an Aurelia application with two different roots, one for loggen in users, and another for anonymous users.

I have in other Aurelia apps implemented a chanaging of app root based on the approach in this answer. This works very well when the login module is an "isolated" module with no additional routes, but I'm having a hard time getting it to work now.

index.js - root for anonymous users

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 for logged in users

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

login code on 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");
            }
        });
}

and...

log off code in auth-service.js

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

The Problem

Setting the different app roots works as expected, the problem is that I would expect the new app root to automatically navigate to the default route of the new root, bit it tries to load the route it was on the moment setRoot(...) is called.

To illustrate with an example,

  1. I'm on the login page. current route: /inloggen
  2. I click the log in button. app.setRoot("ic-app") is called
  3. New root is loaded; configureRouter in ic-app.js is called, and then...
  4. Console error: Route not found: /inloggen

The new root tries to stay in the same /inloggen route, but I would like it to load, or navigate to, the default route for that app root. The same happens on logging out.

How can I force the app to navigate to the default route after changing root?


回答1:


I got this working great, I answered more about how to in this stackoverflow thread:

Aurelia clear route history when switching to other app using setRoot

Basically do the following

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

this.aurelia.setRoot('app');



回答2:


In the router for anonymous users use the mapUnknownRoutes. Like this:

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

Do the same strategy in the other router. Now, try to logout and login again, you will see the user will be redirected to his last screen.

EDIT

Another solution is redirecting to desired route after setting the rootComponent. For instance:

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

Here is a running example https://gist.run/?id=323b64c7424f7bec9bda02fe2778f7fc




回答3:


My best practice would be to simply direct them there, and this is what I do in my applications:

login(username, password) {
  this.auth.login(username, password)
    .then(() => {
      this.aurelia.setRoot('app');
      location.hash = '#/';
    });
}


来源:https://stackoverflow.com/questions/38120388/aurelia-switching-between-app-roots-with-different-route-configurations

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!