【问题标题】:Navigating from canActivate in Aurelia view-model从 Aurelia 视图模型中的 canActivate 导航
【发布时间】:2020-09-23 22:11:46
【问题描述】:

在我的 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 的视图仍然会被激活(即可以在浏览器中看到)。

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

  1. promise 返回truefalse 以接受或拒绝激活此视图。但由于此视图是我的应用程序的一种登录页面,如果被拒绝(返回 false),它会尝试恢复以前的位置,该位置不可用,并引发错误。对于这种特定情况,应用程序也不希望恢复以前的位置。
  2. 另一个想法是做一些类似管道步骤的事情,我们可以做一些类似next.cancel(new Redirect("some/other/view")) 的事情,我们可以指示用新的导航指令取消当前的导航指令。但我不确定如何从视图模型中执行相同的操作。

请提出建议。

解决方法:我终于在ThisView 的视图中使用了一个简单的技巧,即使用if.bind。但是,如果我们能以某种方式取消当前指令(来自页面生命周期)并使用新指令,它可能会更有趣。

【问题讨论】:

    标签: javascript aurelia


    【解决方案1】:

    而不是 this.router.navigate("some/other/view) 你可以不导入重定向并在那里添加重定向,即

    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 来展示它是如何工作的 - 我没有使用 Promise,但我相信这个概念是一样的。

    https://gist.run/?id=52301f1b2898691ff4d54f320f61f6c6

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        您还可以像完成授权步骤一样在路由器管道中注入一些中间件。

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

        可以在此处找到有关如何将步骤添加到路由器管道的一些代码 sn-ps: Aurelia: During a Router's Pipeline Step, how do I bind a variable to that router?

        【讨论】:

        • 感谢您的回答。对此使用管道步骤可能是多余的,因为这只需要执行一次,而管道步骤将针对每个导航请求执行。
        【解决方案4】:

        我想出了另一种在 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);
                    });
                });
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多