如何在angular上使用pushState?

时间:2018-11-23 18:30:03

标签: angular angular-router

我想更改URL而无需重新加载页面。我使用的定位服务是:

this.location.replaceState(`mynewurl`);

当我返回时,历史记录不好。 我找到了html5 pushState解决方案。

我问是否没有像Location这样的服务来处理angular上的pushState

1 个答案:

答案 0 :(得分:1)

您可以按照以下步骤实现它:

  1. import { Routes, RouterModule } from '@angular/router';
  2. 创建路线配置:

const routes: Routes = [
  { path: '', redirectTo: '/videos', pathMatch: 'full' },
  { path: 'videos', component: VideosComponent, children: [
    { path: ':id', component: VideoComponent },
    { path: '**', component: PlaceholderComponent }
  ] },
];
  1. RouterModule.forRoot(routes)添加到imports的{​​{1}}数组中:

@NgModule
  1. 在您的@NgModule({ imports: [..., RouterModule.forRoot(routes), ...], ... }) export class AppModule { } 上添加router-outlet标签,并在app.component.html路线上添加锚标签:

videos
  1. 在videos.component.html中创建另一个带有视频链接的<a routerLink="/videos"> Videos </a> <router-outlet></router-outlet> 标签:

router-outlet
  1. 您现在可以使用... <div> <a routerLink="./1">Video 1</a> | <a routerLink="./2">Video 2</a> | <a routerLink="./3">Video 3</a> | <a routerLink="./4">Video 4</a> | <a routerLink="./5">Video 5</a> | </div> <br> <router-outlet></router-outlet> 在视频组件中获取视频ID。使用它来显示适当的视频:

ActivatedRoute

这是您推荐的Sample StackBlitz

更新:

如果您不想加载所有视频,请不要将import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-video', templateUrl: './video.component.html', styleUrls: ['./video.component.css'] }) export class VideoComponent implements OnInit { videoId; constructor(private activatedRoute: ActivatedRoute) { } ngOnInit() { this.activatedRoute.params.subscribe(params => this.videoId = params['id']); } } 路由作为:id的子路由。对您的路由配置进行此更改:

videos

并摆脱const routes: Routes = [ { path: 'videos', component: VideosComponent }, { path: 'videos/:id', component: VideoComponent }, { path: '', redirectTo: '/videos', pathMatch: 'full' } ]; 中的其他router-outlet。那应该按照您想要的方式。我还更新了示例StackBlitz。

更新2

如果要显示某种模式,则可以使用 ngx-bootstrap 。然后在视频组件的VideosComponent中打开模式。当用户单击以关闭模式时,只需导航回到ngOnInit路线即可。

/videos

在您的模板中:

import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BsModalService } from 'ngx-bootstrap/modal';
import { BsModalRef } from 'ngx-bootstrap/modal/bs-modal-ref.service';
import { LocationListenerService } from '../location-listener.service';

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

  videoId;
  modalRef: BsModalRef;
  @ViewChild('template') template: TemplateRef<any>;

  constructor(
    private activatedRoute: ActivatedRoute,
    private modalService: BsModalService,
    private router: Router
  ) { }

  ngOnInit() {
    this.activatedRoute.params.subscribe(params => this.videoId = params['id']);
    if(!this.modalRef) {
      this.openModal(this.template);
    }
  }

  openModal(template: TemplateRef<any>) {
    this.modalRef = this.modalService.show(template);
  }

  closeModal() {
    this.modalRef.hide();
    this.router.navigate(['/videos']);
  }

}

这应该为您完成工作。我已经重新编辑了示例StackBlitz。看看吧。

PS::点击重叠广告后,它不会导航回到<ng-template #template> <div class="modal-header"> <h4 class="modal-title pull-left">Modal</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="closeModal()"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <p> Playing Video {{ videoId }} </p> </div> </ng-template> ,但模式会关闭。这只是一种情况,您可以自己处理。休息我在答案中解释的所有内容。希望这会有所帮助。

更新3:

要在后台显示视频,您必须再次创建/videos路径,该路径是':id'路径的子级。但这又需要您将所有视频都显示在前面,这是您要避免的情况。

无论如何,考虑到您最近要求我实现的目标,我已经对StackBlitz进行了更新。