首页 文章

在Angular 2中更改当前路径上的单个路径参数

提问于
浏览
23

是否可以在保留所有其他参数的同时更改当前路径中的单个路径参数?这用于寻呼组件,该寻呼组件将路由到新页面,同时保持当前路由的其他部分相同 .

一些例子:

  • 第2页的默认页面: orders?foo=foo&bar=bar > orders?foo=foo&bar=bar&page=2

  • 默认页面到第2页(子): orders/;foo=foo;bar=bar > orders/;foo=foo;bar=bar;page=2

  • 有关参数的子项和父项的第2页到第3页: orders/;foo=foo;page=2?bar=bar > orders/;foo=foo;page=3?bar=bar

我尝试使用 routerLink ,但是这会丢失原本不属于路由器链接的任何其他参数 .

我也尝试使用当前的 Router 获取当前路径的 Instruction ,但是在调用 navigateByInstruction() 时,更改 Instruction 的参数似乎没有任何影响 .

4 回答

  • 2

    你可以使用查询参数选项代替它使用的参数

    在调用组件

    const navigationExtras: NavigationExtras = {
      queryParams: { 'param_id': 1, 'param_ids': 2, 'list':[1,2,3] },
    };
    this.router.navigate(['/path'], navigationExtras);
    

    在被调用的组件中

    this.route.queryParamMap.map(params =>  params.get('param_id') || 
        'None').subscribe(v => console.log(v));
      this.route.queryParamMap.map(params =>  params.get('param_ids') || 
            'None').subscribe(v => console.log(v));
      this.route.queryParamMap.map(params =>  params.getAll('list') || 
                'None').subscribe(v => console.log(v));
    
  • 0

    如果activeRoute在调用router.navigate(nextroutearray)之前可以返回当前route []的简单克隆,我会很高兴,但我没有在api中找到这样的方法 .

    因此,我将需求集中到一个简单的服务中,我可以解析当前的activeRoute,这是一组用于下一个路由的参数 . 我不认为这段代码会覆盖路由中url的所有复杂性,但在我的情况下,我只在路由的最后部分使用参数,所以它对我有用:

    服务方法如下所示:

    routeFor(activeRoute: ActivatedRoute, params: any): any[] {
        let result = [];
        result.push('/');
        for (var i = 0; i < activeRoute.pathFromRoot.length; i++) {
            activeRoute.pathFromRoot[i].snapshot.url.forEach(r => result.push(r.path));
        }
    
        let currentParams = activeRoute.pathFromRoot[activeRoute.pathFromRoot.length - 1].snapshot.url[0].parameters;
        for (var n in currentParams) {
            if (currentParams.hasOwnProperty(n) && !params.hasOwnProperty(n)) {
                params[n] = currentParams[n];
            }
        }
    
        result.push(params);
        return result;
    }
    

    然后我可以在任何组件中使用此方法来注入我的站点 Map 服务:

    setNextTab(tab: string) {
        let nextUrl = this.sitemapService.routeFor(this.activatedRoute, { pagetab: tab });
        this.router.navigate(nextUrl);
    }
    

    在html中,setNextTab方法的链接如下所示:

    <li (click)="setNextTab('myTabName')">Next tab</li>

  • 0

    为什么你根本不这样做:

    <a [routerLink]="['./Cmp', {limit: 10, offset: 10}]">Previous Page</a>
    <a [routerLink]="['./Cmp', {limit: 10, offset: 20}]">Next Page</a>
    
  • 2

    这很容易 . 假设我们的ListComponent中有一个方法可以更改页面并保持所有其他参数不变(如搜索相关参数 - 无法更改页面,忘记我们正在搜索的东西:):

    page (page) {
        this.list.page = page;
        this._router.navigate([this.list.route, _.assign(this._params.params, { page: page })]);
        this.update(); // Update your list of items here
    }
    

    我使用Underscore将一个页面参数分配给我的私有注入的RouteParams对象的现有参数映射 . 该 Map 在导航时更新,所以我们都很好,只记得你不能直接改变它,它是不可改变的 .

    这是我对文章列表的实现,以及用作提供分页的指令的分页组件:

    ArticleListComponent:

    @Component({
        selector: 'articles',
        templateUrl: './article/list/index.html',
        directives: [PaginationComponent],
        providers: [ArticleService]
    })
    export class ArticleListComponent implements OnInit {
        list: ArticleList = new ArticleList;
    
        private _urlSearchParams: URLSearchParams = new URLSearchParams;
    
        constructor (
            private _article: ArticleService,
            private _router: Router,
            private _params: RouteParams,
            private _observable: ObservableUtilities
        ) {}
    
        update () {
            this._observable.subscribe(this._article.retrieveRange(this.list));
        }
    
        ngOnInit () {
            let page = this._params.get("page");
            if(page) {
                this.list.page = Number(page);
            }
    
            // check for size in cookie 'articles-per-page'
    
            let title = this._params.get("title");
            if (title) {
                this.list.title = title;
            }
    
            this.update();
        }
    
        size (size: number) {
            // set cookie 'articles-per-page'
        }
    
        page (page) {
            this.list.page = page;
            this._router.navigate([this.list.route, _.assign(this._params.params, { page: page })]);
            this.update();
        }
    
        search () {
            this.list.page = 1;
            let params = _.pick({
                title: this.list.title
            }, _.identity);
            this._router.navigate([this.list.route, params ]);
        }
    }
    

    PaginationComponent:

    import { Component, Input, Output, EventEmitter, OnInit } from 'angular2/core';
    import { RouteParams } from 'angular2/router';
    import  _ from 'underscore';
    
    import { List } from '../common/abstract';
    
    @Component({
        selector: 'pagination',
        templateUrl: './pagination/index.html'
    })
    export class PaginationComponent implements OnInit {
        @Input() list: List;
        @Output() change  = new EventEmitter<number>();
    
        pages: Array<number> = [];
    
        constructor(
            private _params: RouteParams
        ) {}
    
        ngOnInit () {
            this.pages = _.range(1, this.list.pages + 1);
        }
    
        onClick (page: number) {
            if (page > 0 && page <= this.list.pages) {
                this.change.emit(page);
            }
            return false;
        }
    
        href (page: number) {
            return `${this.list.uri}?${_.map(_.assign(this._params.params, { page: page }), (value, param) => `${param}=${value}`).join('&')}`;
        }
    
        first (page) {
            return page == 1 ? 1 : null;
        }
    
        last(page) {
            return page == this.list.pages ? this.list.pages : null;
        }
    }
    

    分页模板(index.html) - 我使用bootstrap进行样式设计

    <div>
            <ul class="pagination">
                <li [class.disabled]="first(list.page)"><a (click)="onClick(list.page - 1)" [attr.href]="href(list.page - 1)">&laquo;</a></li>
    
                <template ngFor let-page [ngForOf]="pages">
                    <li *ngIf="(page >= list.page - 2 && page <= list.page + 2) || first(page) || last(page)" [ngSwitch]="(page != list.page - 2 && page != list.page + 2) || first(page) || last(page)" [class.active]="page == list.page">
                        <a *ngSwitchWhen="true" (click)="onClick(page)" [attr.href]="href(page)">{{page}}</a>
                        <a *ngSwitchDefault (click)="onClick(page)" [attr.href]="href(page)">...</a>
                    </li>
                </template>
    
                <li [class.disabled]="last(list.page)"><a (click)="onClick(list.page + 1)" [attr.href]="href(list.page + 1)">&raquo;</a></li>
            </ul>
        </div>
    

    文章列表模板中的用法:

    ...
    <pagination *ngIf="list.pages > 1" [(list)]="list" (change)="page($event)" class="text-center"></pagination>
    ...
    

    我的小项目中的文章服务使用Range标头从服务器请求一系列文章 .

    希望你觉得这很有帮助!

相关问题