使用选项参数路由?和 &

Routing with option params with ? and &

我想深入了解 angular 的路线,但没有成功。我想做的是使用 angular 的路由捕获 url 中的每个参数。

所以让我们以此为例 url:

http://localhost:4200/PUC/#/P3?MODE=P&USER=AE13356&PROJECT=00001&PROTOCOL=00002&VERSION=1

我正在尝试将参数分配给一些变量。

所以我所做的(错误的)是这样的:

路线:

 RouterModule.forRoot(
      [
        { path: "", component: AppComponent, pathMatch: 'full'},
      ],
    )

组件:

@Component({
  selector: 'app-main',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{

  constructor(
    private router: Router,
    private route: ActivatedRoute
  ) { }

  ngOnInit(){
    let queryParams = this.route.snapshot.queryParams;
    const mode = queryParams['MODE'];

    console.log("ID > " + mode);
  }
}

但是queryParams始终是一个空对象。我错过了什么?

编辑

使用location.href我得到了整个url,我可以用这种方式对我得到的数据做一些逻辑吗?基本上我要做的是,如果 PROJECT 有一个值,则加载一个组件,如果 PROJECT 不在 url.

中,则加载另一个组件

Snapshot 不会在 queryParams 发生变化时为您提供更新后的信息。但是 ActivatedRoute 上有一个 queryParams BehaviorSubject 可以为您提供更新的查询参数。

您应该为此使用 route.queryParams.subscribe

现在,我不确定如何处理您 URL 中的 #。但是如果没有它,因为你有 PUC 作为路由和 P3 作为它的 child,你的路由配置看起来像这样:

RouterModule.forRoot([
  {
    path: 'PUC/:segment',
    component: PucComponent
  }
])

至于路线 PIC,我们正在加载 PucComponent,您应该阅读 queryParams 那里的

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-puc',
  templateUrl: './puc.component.html',
  styleUrls: ['./puc.component.css']
})
export class PucComponent implements OnInit {

  constructor(
    private router: Router,
    private route: ActivatedRoute
  ) { }

  ngOnInit(){
    this.route.queryParams
      .subscribe(queryParams => console.log(queryParams));
  }

}

这里有一个 Sample StackBlitz 供您参考。

通过订阅阅读

import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-user-detail',
  templateUrl: 'user-detail.component.html'
})
export class UserDetailComponent implements OnInit {
    constructor(private activeRoute: ActivatedRoute) {
    }

ngOnInit() {
    this.activeRoute.queryParams.subscribe(queryParams => {
        // do something with the query params
    });

    this.activeRoute.params.subscribe(routeParams => {
        this.loadUserDetail(routeParams.id);
    });
}

肮脏的方式

通过如下嵌套订阅者:

ngOnInit() {
    // Nest them together and
    this.activeRoute.queryParams.subscribe(queryParams => {
        this.activeRoute.params.subscribe(routeParams => {
            this.loadUserDetail(routeParams.id, queryParams.type);
        });
    });
}

或者你可能想写一个不同的版本,即将这些嵌套回调移动到一个辅助函数,然后再传递给它另一个接受查询和路由参数的回调,即

ngOnInit() {
    this.readUrlParams((routeParams, queryParams) => {
        this.loadUserDetail(routeParams.id, queryParams.type);
    });
}

readUrlParams(callback) {
    // Nest them together and
    this.activeRoute.queryParams.subscribe(queryParams => {
        this.activeRoute.params.subscribe(routeParams => {
            callback(routeParams, queryParams);
        });
    });
}

使用 RxJS

RxJS 是一个非常强大的库,你可以通过几种不同的方式来实现,但我最喜欢并且发现自己使用最多的一种是使用 combineLatest 运算符,我们使用它合并路由和查询参数并拥有一个单独的可观察对象在一个对象中给我们两个。这是我们更新后的示例的样子

import { ActivatedRoute } from '@angular/router';

// Add the observable and combineLatest
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/combineLatest';

@Component({
  selector: 'app-user-detail',
  templateUrl: 'user-detail.component.html'
})
export class UserDetailComponent implements OnInit {
    constructor(private activeRoute: ActivatedRoute) {
    }

    ngOnInit() {
        // Combine them both into a single observable
        const urlParams = Observable.combineLatest(
          this.activatedRoute.params,
          this.activatedRoute.queryParams,
          (params, queryParams) => ({ ...params, ...queryParams})
        );

        // Subscribe to the single observable, giving us both
        urlParams.subscribe(routeParams => {
            // routeParams containing both the query and route params
            this.loadUserDetail(routeParams.id, routeParams.type);
        });
    }
}

您所要做的就是将查询参数的值包含在 " "" 中。

<a [routerLink]="['/PUC','P3']" [queryParams]="{key:'stringvalue'}">Click here</a>

包含在中" "如果查询参数的值为数字,则不需要

<a [routerLink]="['/PUC','P3']" [queryParams]="{key:number}">Click here</a>

app.moudle.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule,Routes } from '@angular/router';
import { HelloComponent } from './hello.component';
import { AppComponent } from './app.component';

const routes:Routes = [{
       path:'PUC/P3', component:HelloComponent
    }]
@NgModule({
  imports:[ BrowserModule,FormsModule ,RouterModule.forRoot(routes,{useHash:true})],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

app.component.html

<a [routerLink]="['/PUC','P3']" [queryParams]="{ MODE: 'p', USER:'AE13356',PROJECT:00001,PROTOCOL:00002,VERSION:1}"> Click here</a>
<router-outlet></router-outlet>

hello.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-hello',
  template: `<h2>Check Console for Output</h2>`,
})
export class HelloComponent implements OnInit {
  constructor(private route:ActivatedRoute){}
  ngOnInit(){
    this.route.queryParams.subscribe((query)=>{
      console.log(query);
      console.log("MODE",query['MODE']);//output MODE:p
    });
  }
}

您还可以看到有效的解决方案here in stackblitz