Javascript 在Aurelia视图模型中从canActivate导航

Javascript 在Aurelia视图模型中从canActivate导航,javascript,aurelia,Javascript,Aurelia,在我的Aurelia视图模型中,我试图在canActivate()中检查一些先决条件,并根据这些先决条件决定是否导航到其他视图 export class ThisView{ canActivate() { const self = this; const promise = self.services.get(url) .then((items: any) => { if (i

在我的Aurelia视图模型中,我试图在
canActivate()
中检查一些先决条件,并根据这些先决条件决定是否导航到其他视图

export class ThisView{

    canActivate() {        
        const self = this;
        const promise = self.services.get(url)
            .then((items: any) => {
                if (items) {
                    self.items= items;
                    if (self.items.length === 1) {
                        this.router.navigate("some/other/view");
                        //return false; 
                    }
                    //return true;
                } else {
                    self.logger.error("No item found");
                    //return false;
                }                
            });
        return promise;
    }
}
现在,即使我正在导航到
some/other/view
,如果只找到一个项目,
ThisView
的视图仍然会被激活(即可以在浏览器中看到)

有没有办法避免这种情况?我为此做了几件事

  • promise
    返回
    true
    ,或
    false
    以接受或拒绝激活此视图。但由于此视图是我的应用程序的登录页,如果被拒绝(返回false),它将尝试恢复以前不可用的位置,并抛出错误。对于这种特定情况,应用程序也不希望恢复以前的位置
  • 另一个想法是执行类似管道步骤的操作,我们可以执行类似于
    next.cancel(新重定向(“some/other/view”))
    ,其中我们可以指示使用新的导航指令取消当前导航指令。但我不知道如何从视图模型中执行相同的操作
  • 请建议


    解决方法:我终于使用了一个简单的技巧,在
    此视图的视图上使用
    if.bind
    。然而,如果我们能够以某种方式用新指令取消当前指令(从页面生命周期中删除),它可能会更有趣。

    您还可以按照执行授权步骤的相同方式在路由器管道中插入一些中间件

    然后,您将在特定步骤中调用服务,并根据结果路由到不同的视图

    有关如何将步骤添加到路由器管道的一些代码片段可在此处找到:

    代替此.router.navigate(“某些/其他/视图”)您不能导入重定向并在其中添加重定向,即

    import {Redirect} from 'aurelia-router';
    
    export class ThisView{
    
    canActivate() {        
        const self = this;
        var items = self.services.get(url);
        if(items){
            self.items= items;
            if (self.items.length === 1) {
               return new Redirect("some/other/view");
            }
            return true;
        } 
        else {
            self.logger.error("No item found");
            return new Redirect("not-found-view");
        }                
    }
    
    }

    我已经做了一个基本的GistRun来展示它是如何工作的——我没有使用承诺,但我相信这个概念是相同的

    您可以使用
    激活()
    事件来处理路由器导航。抛出错误以停止导航或转到/重定向到其他位置。示例:

    import {Router} from 'aurelia-router';
    
    export class SampleModel {
      static inject() { return [Router] };
    
      constructor(router) {
        this.router = router;
      }
    
      activate(){
        if(this.somedata === null){
          // stop navigation or goto start location
          if(this.router.history.previousLocation){
            // stop from navigation
            throw new Error('Wrong data');
          }else{
            // return to start page
            this.router.navigate('start');
          }
        }
      }
    }
    

    我找到了另一种在canActive()中处理导航的方法


    谢谢您的回答。使用管道步骤可能有点过分,因为这只需要执行一次,而管道步骤将针对每个导航请求执行。
       canActivate(params, routeConfig, navigationInstruction) {
    
            return new Promise((resolve, reject) => {
    
                this.api.request(params.id).then(result => {
    
                    if (result) {
                        resolve(true);
                    } else {
                        toastr.error('Invalid URL');
                        reject(navigationInstruction.router.navigate('/xxx'));
                    }
                }).catch(error => {
                    toastr.error('Request error');
                    resolve(false);
                });
            });
        }