2016-12-05 4 views
3

TL; DR - Wie kann ich verzögern die ProcessResult() Funktion in aurelia-router.js von der Ausführung, weil ich bin immer noch auf dem Ergebnis eines Versprechens in meinem Code warten? Es ergibt sich das richtige Modul-Rendering mit der falschen Adresse/href.Aurelia - Warten auf ein Versprechen im Router Prerender Schritt zurückzukehren

Beispiel: Wenn Sie auf Basis-Modul sind, dann auf Admin klicken, wird das Admin-Modul laden, aber die href bleibt www.mycompany.com/#/base-module statt www.mycompany.com/#/admin, und dieser Fehler kann in der Konsole zu sehen:

ERROR [app-router] Error: Expected router pipeline to return a navigation result, but got [{}] instead

Längere Version:

ich habe einen Prerender Schritt in meinem Router, wird der Benutzer für ein bestimmtes Modul aktiviert wird geprüft, ob vor der Ansicht zu machen.

In meiner PreRenderStep-Klasse habe ich eine run-Funktion, die einen Mediator aufruft, um die Berechtigungen für einen Benutzer abzurufen, und überprüft dann, ob das Modul, auf das der Benutzer geklickt hat, in der Liste der aktivierten Module enthalten ist. Der Anruf beim Mediator beinhaltet ein Versprechen.

Das Problem besteht darin, dass das Ausführungsversprechen im Prerender-Schritt verrechnet wird, bevor ein Versprechen innerhalb der Ausführungsmethode abgeschlossen wird. Daher wird die Ansicht schließlich gerendert (weil der Benutzer aktiviert ist), aber die vorherige href verbleibt in der Adressleiste.

Router:

configureRouter(config, router) { 
 
     config.title = "Tramonex"; 
 
     config.addPipelineStep('authorize', AuthorizeStep); 
 
     config.addPreRenderStep(PreRenderStep); 
 
     config.map([ 
 
      { 
 
       route: ['', 'log-in-out'], 
 
       name: 'home', 
 
       moduleId: 'modules/authentication/log-in-out' 
 
      }, 
 
      { 
 
       route: 'passwordReset', 
 
       moduleId: 'modules/authentication/password-reset', 
 
      }, 
 
      {route: 'app', moduleId: 'app', auth: true}, 
 
      { 
 
       route: 'base-module', 
 
       name: 'base-module', 
 
       moduleId: 'modules/base-module', 
 
       href: 'base-module', 
 
       nav: true, 
 
       auth: true 
 
      }, 
 
      { 
 
       route: 'test1', 
 
       name: 'test1', 
 
       moduleId: 'modules/test1/test1', 
 
       href: 'test1', 
 
       nav: true, 
 
       auth: true, 
 
       settings: {moduleAuthRequired: true} 
 

 
      }, 
 
      { 
 
       route: 'test2', 
 
       name: 'test2', 
 
       moduleId: 'modules/test2/test2', 
 
       href: 'test2', 
 
       nav: true, 
 
       auth: true, 
 
       settings: {moduleAuthRequired: true} 
 
      }, 
 
      { 
 
       route: 'admin', 
 
       name: 'admin', 
 
       moduleId: 'modules/admin/admin', 
 
       href: 'admin', 
 
       nav: true, 
 
       auth: true, 
 
       settings: {moduleAuthRequired: true} 
 
      }, 
 
     ]); 
 

 
     this.router = router; 
 
    } 
 
}

PreRenderStep:

@inject(Mediator, AuthenticationService) 
 
class PreRenderStep { 
 

 
    constructor(mediator, authenticationService) { 
 
     this.mediator = mediator; 
 
     this.authenticationService = authenticationService; 
 
    } 
 

 
    run(navigationInstruction, next) { 
 
     
 
     if (navigationInstruction.getAllInstructions().some(i => i.config.settings.moduleAuthRequired)) { 
 

 
      this.redirect = false; 
 
      this.mediator.getPermissionsForUser() 
 
       .then(user => { 
 
        userPerms = user.modules; 
 
        var isEnabled = userPerms.includes(navigationInstruction.config.name); 
 
        if (!isEnabled) { 
 
         this.redirect = true; 
 
        } 
 
       }) 
 
       .then(() => { 
 
        return this.redirect next.cancel(navigationInstruction.router.navigateToRoute('base-module')) : next(); 
 
       }); 
 
     } 
 
     else { 
 
      return next(); 
 
     } 
 
    } 
 
}

Wenn der Benutzer auf ein Modul klickt, das eine Authentifizierungsüberprüfung erfordert, wird der Code ausgelöst, und während wir auf das Versprechen von mediator.getPermissionsForUser() warten, wird dieser Code in aurelia-router.js (die Linien mit Sternen):

function processResult(instruction, result, instructionCount, router) { 
 
    if (!(result && 'completed' in result && 'output' in result)) { 
 
    result = result || {}; 
 
    **result.output = new Error('Expected router pipeline to return a navigation result, but got [' + JSON.stringify(result) + '] instead.');** 
 
    } 
 

 
    var finalResult = null; 
 
    if (isNavigationCommand(result.output)) { 
 
    result.output.navigate(router); 
 
    } else { 
 
    finalResult = result; 
 

 
    if (!result.completed) { 
 
     if (result.output instanceof Error) { 
 
     logger.error(result.output); 
 
     } 
 

 
     **restorePreviousLocation(router);** 
 
    } 
 
    }

+1

Funktioniert es, wenn Sie das Versprechen von Ihrem prerender Schritt zurückgeben: return this.mediator.getPermissionsForUser(). Dann ...? – mgiesa

+0

Es gibt auch einen Authorize-Schritt, der zuerst ausgeführt wird, der sich wie der richtige Ort für diese Überprüfung anfühlt. – mgiesa

+1

[Diese Antwort] (http://stackoverflow.com/a/36339620/3478010) schlägt vor, dass Sie möglicherweise nur eine Rückkehr verpassen , also 'return this.mediator.getPermissionsForUser(). dann (...)' –

Antwort

1

Sie müssen das Versprechen zurückzukehren, die Sie im Run-Funktion sind zu schaffen.

return this.mediator.getPermissionsForUser() 
Verwandte Themen