簡體   English   中英

從 Aurelia 視圖模型中的 canActivate 導航

[英]Navigating from canActivate in Aurelia view-model

在我的 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")) ,我們可以在其中指示使用新的導航指令取消當前導航指令。 但我不確定如何從視圖模型中做同樣的事情。

請建議。

解決方法:我終於使用了一個簡單的技巧, if.bindif.bind視圖上使用ThisView 然而,如果我們能以某種方式用新指令取消當前指令(來自頁面生命周期),它可能會更有趣。

而不是 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 來展示它是如何工作的——我沒有使用承諾,但我相信這個概念是一樣的。

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

您可以使用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');
      }
    }
  }
}

您還可以以與完成授權步驟相同的方式在路由器管道中注入一些中間件。

然后,您將在特定步驟中調用您的服務,並根據結果路由到不同的視圖。

可以在此處找到有關如何將步驟添加到路由器管道的一些代碼片段: Aurelia:在路由器的管道步驟期間,如何將變量綁定到該路由器?

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM