如何订阅特定的子路由参数?

时间:2017-11-15 07:38:20

标签: angular angular2-routing

我有这两个路线定义,产品清单和产品详细信息:

const routes: Routes = [
    ...
    {
        path: 'product',
        component: ProductListComponent,
        resolve: {
            products: ProductListResolverService
        },
        children: [
            {
                path: ':productcode',
                component: ProductDetailComponent,
                resolve: {
                    product: ProductDetailResolverService
                }
            },
            ...
        ]
    }
    ...

在产品列表组件中,我有一组单选按钮,用于指示选择了哪个产品,而路由器插座则显示产品详细信息组件:

<div *ngFor="let product of Products" class="radio">
    <label>
        <input [(ngModel)]="SelectedProduct" 
            [value]="product" 
            (change)="RefreshDetail()" 
            name="selectedProduct" 
            type="radio"> 
            {{product.Name}} {{product.Code}}
    </label>
</div>
<router-outlet></router-outlet>

当用户单击单选按钮时,URL,产品详细信息组件和单选按钮会正确同步。

但是,当用户直接访问某个产品网址时,网址和产品详细信息组件会显示正确的产品,但单选按钮则不会。我直接转到某个产品网址的意思是用户将URL输入浏览器地址栏并按Enter键。

我试图从ActivatedRoute获取:productcode的值,但它不起作用:

this.route.paramMap.subscribe(params => {
  let productcode = params.get("productcode");

  let product = this.Products.find(product => product.Code == productcode);

  if (!!product) {
    this.SelectedProduct = product;
  }
});

paramMap.get("productcode")始终为空。可能是因为它不在产品列表路径中,而是在子路径中,产品详细信息路径中。

我还没有找到从产品列表组件订阅产品详细信息路径的方法。除了产品细节路线不是产品列表路线的唯一孩子。

如何订阅特定的子路由参数?

2 个答案:

答案 0 :(得分:3)

更好的方法之一是使用服务和observable。因此,每当子组件发生更改时,新数据将立即反映在父组件中(特别是当您刷新页面时,您可以保留父组件状态)。

在您的ProductDetailComponent中,

import { Subscription } from 'rxjs';
import { Router, ActivatedRoute } from '@angular/router';
import { ProductService } from './product.service';


export class ProductDetailComponent {
    private subscription:Subscription;

    constructor(private activatedRoute:ActivatedRoute, private productService:productService){
    }

    public ngOnInit() {
      let vm = this;
      this.subscription = this.activatedRoute.params.subscribe(
          (param: any) => {
            if(typeof param['productcode'] !== 'undefined' && param['productcode'].trim !='' &&  typeof param['productcode']!=null){
               vm.productService.changedProductCode(param['productcode']);
            }
      });
    }
}

在product.service.ts中,

import { Subject } from 'rxjs/Subject'
import { Observable } from 'rxjs/Rx';

@Injectable()
export class myService {

  private productCode = new Subject<string>();

  productCodeChange$ = this.productCode.asObservable();
  changedProductCode(option:any){
        this.productCode.next(option);
  }
}

现在,要在父组件中获取已更改的产品ID,

ProductListComponent.ts

import { Subscription } from 'rxjs';
import { ProductService } from './product.service';

export class ProductListComponent {

    private subscription:Subscription;

    constructor(private productService:productService){

        this.productService.productCodeChange$.subscribe( /* get called on every child page changes*/
         code => {

        console.log(code); // you get your passed code value in 'code' variable

        let product = this.Products.find(product => product.Code == code);

        if (!!product) {
          this.SelectedProduct = product;
        }
    });
  }
}

答案 1 :(得分:0)

尝试这样:

this.route.params.subscribe((params) => {

    let productcode = params['productcode'];

    let product = this.Products.find(product => product.Code == productcode);

    if (!!product) {
       this.SelectedProduct = product;
    }
});