Aurelia动态地/从fetch加载路由

时间:2016-06-06 00:02:08

标签: aurelia

我想动态加载菜单选项。所以我想知道最好的方法

我可以在加载页面后使用以下代码添加路由。这适用于普通导航,但在刷新期间不起作用。

可以配置路由器返回一个承诺/如何将菜单项加载到路径中?

 @inject(HttpClient)
 export class DocumentMenu {
  router: Router;
  documents : IDocument[];
  heading = 'Document Router';

  constructor(public http: HttpClient) {}

 activate(): void {

    this.http.fetch('http://localhost:17853/Document/GetDocuments?folderID=13244')
      .then<IDocument[]>(response => response.json())
      .then<IDocument[]>(docs => {    
      if ( docs ){
        for( var doc of docs){
          this.router.addRoute( { route : doc.DocumentID.toString(), name : doc.Name, moduleId: './documents/document', nav:true, title: doc.Name });
        }
        this.router.refreshNavigation();
      }
      return docs;
    });

 }

configureRouter(config: RouterConfiguration, router: Router) {

  var routes = new Array();
  routes.push( 
  { route: 'index', name: 'index-name', moduleId: './documents/index', nav: false, title: 'Documents' } );
  routes.push(       { route: '', redirect: 'index' } );

  config.map( routes );
  this.router = router;
}
}

4 个答案:

答案 0 :(得分:10)

这不能回答你的问题,但我认为这对你和其他有类似问题的人有帮助。

动态路线反模式

您的应用程序有许多不同的路由,所有路由都根据应用程序的状态而有所不同。因此,您必须首先获取数据,然后构建路由,然后将其注册到路由器。

这是一种反模式的原因是因为当Aurelia本身使用描述动态内容的静态方式构建时,您将不断需要根据应用程序的状态更新路由器。

动态路由同构数据

假设您正在构建Google云端硬盘,并且您有许多可在用户添加和删除它们时更改的各种文件。对于这种情况,您有两类路线:文件夹和文档。因此,您为每个路线制作一条路线。

configureRouter(config) {
    config.map([
        { route: 'folder/:id', moduleId: 'folder' }
        { route: 'document/:id', moduleId: 'document' }
    }
}

class FolderViewModel {
    activate({ id }) {

        // get your specific folder data and load it into your folder view model
        this.fetch('getDocuments?folderId=${id}')
    }   
}

class DocumentViewModel {
    activate({ id }) {

        // get your specific document and load it into your document view model
        this.fetch('getDocuments?documentId=${id}')
    }
}

动态路由异构数据

让我们说你想建立YouTube。当user mjd10d登录时,欢迎他观看视频内容,但他不是优质内容创作者,也无法访问网站的内容创建部分。处理此问题的最佳方法是在应用程序中保留所有可能的路由,并根据AuthorizeStep中的用户凭据对其进行过滤。

configureRouter(config, router) {
  config.addPipelineStep('authorize', AuthorizeStep);
}

@inject(UserSession)
class AuthorizeStep {

  constructor(UserSession) {
    this.user = UserSession;
  }

  run(navigationInstruction, next) {
    var instructions = navigationInstruction.getAllInstructions()
    if (!this.authorized(instructions.config)) {
      return Redirect('404');
    }
    return next();
  }

  authorized(routeConfig) {

    // something smart that returns false if unauthorized
    return this.user.permissionLevel > routeConfig.requiredPermission;
  }
}

虽然并非所有情况都与授权相关,但您始终可以使用addPipelineStep API注册自己的管道步骤

答案 1 :(得分:0)

您可以通过在&#34; configureRouter&#34;中使用单个固定(静态)路由动态地(在启动时或在任何时间)添加路由。方法(在app.ts中),然后在你的提取完成时动态地添加所有其他路由,如下所示:

var result =  from A in DataContext<A>()
              .Include(x => x.B)
              .Include(x => x.B.C)
              .Orderby(x => x.C)
              .ThenBy(x => x.B)
              .ThenBy(x => x.A)
              .Skip(pageNumber * pageSize)
              .Take(pageSize);

&#34; routeMaps&#34; function只是repo调用的一个包装器,以及结果到路由项Array的映射。

答案 2 :(得分:0)

您可以在激活时返回承诺。如果activate()返回一个promise,则configureRouter()不会触发,直到在activate()中返回的promise被解析。

我最终准备了以下激活路线:

activate(){
    return this.http.fetch('url')
       .then(response => response.json())
       .then(docs => {    
           this.routerMapped = docs;
       });       
}

configureRouter(config, router) {
    //build the routes from this.routermapped if necessary
    config.map( this.routerMapped );
    this.router = router;  
}

答案 3 :(得分:-1)

为了使这项工作,我使用同步请求

在构造函数中创建了路由
export class DocumentMenu {
...
routes  : RouteConfig[];

constructor(http: HttpClient) {
  this.http = http;

  var folderID = window.location.hash.split('/')[2]

  this.routes = new Array<RouteConfig>();
  this.routes.push ( { route: 'index', name: 'index-name', moduleId: './documents/index', nav: false, title: 'Documents' });
  this.routes.push ( { route: '', redirect: 'index' } );

  for( var route of this.getRoutes( folderID )){
    this.routes.push( route );
  }
}

getRoutes(folderID: string) :  RouteConfig[]
{
  var routes = new Array<RouteConfig>();
  var docsURL = 'http://localhost:17853/Document/GetDocuments?folderID=' + folderID;

  // synchronous request   
  var docsResp = $.ajax({
      type: "GET",
      url: docsURL,
      async: false,
      cache:false
  }).responseText;

  var docs = JSON.parse( docsResp );

  for( var doc of docs ){
    routes.push( { route : doc.DocumentID.toString(), name : doc.Name, moduleId: './documents/document', nav:true, title: doc.Name });
  }

  return routes;
}

configureRouter(config: RouterConfiguration, router: Router) {  
   config.map( this.routes );
   this.router = router;
 }
...