如何在 angular 上使用 pushState?
How to use pushState on angular ?
我想在不重新加载页面的情况下更改 url。我使用这样的定位服务:
this.location.replaceState(`mynewurl`);
当我返回时,历史记录不好。
我找到了 html5 pushState 解决方案。
我问是否没有像 Location 这样的服务来处理 angular
上的 pushState
您可以按照以下步骤来实现:
import { Routes, RouterModule } from '@angular/router';
- 创建路由配置:
const routes: Routes = [
{ path: '', redirectTo: '/videos', pathMatch: 'full' },
{ path: 'videos', component: VideosComponent, children: [
{ path: ':id', component: VideoComponent },
{ path: '**', component: PlaceholderComponent }
] },
];
- 将
RouterModule.forRoot(routes)
添加到 @NgModule
的 imports
数组中:
@NgModule({
imports: [..., RouterModule.forRoot(routes), ...],
...
})
export class AppModule { }
- 将
router-outlet
标记添加到您的 app.component.html
以及将锚标记添加到 videos
路线:
<a routerLink="/videos">
Videos
</a>
<router-outlet></router-outlet>
- 在 videos.component.html 中创建另一个带有视频链接的
router-outlet
标签:
...
<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>
- 您现在可以使用
ActivatedRoute
获取视频组件中的视频 ID。用它来显示合适的视频:
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']);
}
}
这里有一个 Sample StackBlitz 供您参考。
更新:
如果您不想加载所有视频,请不要将 :id
路由作为 videos
的子路由。对您的路由配置进行此更改:
const routes: Routes = [
{ path: 'videos', component: VideosComponent },
{ path: 'videos/:id', component: VideoComponent },
{ path: '', redirectTo: '/videos', pathMatch: 'full' }
];
并从 VideosComponent
中删除额外的 router-outlet
。那应该按照您想要的方式进行。我也更新了示例 StackBlitz。
更新 2
如果你想显示某种模式,那么你可以使用ngx-bootstrap
。然后在视频组件的 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']);
}
}
在您的模板中:
<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">×</span>
</button>
</div>
<div class="modal-body">
<p>
Playing Video {{ videoId }}
</p>
</div>
</ng-template>
这应该可以为您完成工作。我重新编辑了示例 StackBlitz。随便看看。
PS: 它不会导航回 /videos
覆盖点击但模式将关闭。这只是您可以自己处理的一种情况。休息我在答案中解释的所有内容。希望这有帮助。
更新 3:
为了在后台显示视频,您必须再次创建 ':id'
路径,使其成为 videos
路径的子路径。但这又会要求您提前显示所有视频,这是您希望避免的情况。
考虑到您最近要求我实现的目标,我已经对 StackBlitz 进行了更新。
我想在不重新加载页面的情况下更改 url。我使用这样的定位服务:
this.location.replaceState(`mynewurl`);
当我返回时,历史记录不好。 我找到了 html5 pushState 解决方案。
我问是否没有像 Location 这样的服务来处理 angular
上的 pushState您可以按照以下步骤来实现:
import { Routes, RouterModule } from '@angular/router';
- 创建路由配置:
const routes: Routes = [
{ path: '', redirectTo: '/videos', pathMatch: 'full' },
{ path: 'videos', component: VideosComponent, children: [
{ path: ':id', component: VideoComponent },
{ path: '**', component: PlaceholderComponent }
] },
];
- 将
RouterModule.forRoot(routes)
添加到@NgModule
的imports
数组中:
@NgModule({
imports: [..., RouterModule.forRoot(routes), ...],
...
})
export class AppModule { }
- 将
router-outlet
标记添加到您的app.component.html
以及将锚标记添加到videos
路线:
<a routerLink="/videos">
Videos
</a>
<router-outlet></router-outlet>
- 在 videos.component.html 中创建另一个带有视频链接的
router-outlet
标签:
...
<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>
- 您现在可以使用
ActivatedRoute
获取视频组件中的视频 ID。用它来显示合适的视频:
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']);
}
}
这里有一个 Sample StackBlitz 供您参考。
更新:
如果您不想加载所有视频,请不要将 :id
路由作为 videos
的子路由。对您的路由配置进行此更改:
const routes: Routes = [
{ path: 'videos', component: VideosComponent },
{ path: 'videos/:id', component: VideoComponent },
{ path: '', redirectTo: '/videos', pathMatch: 'full' }
];
并从 VideosComponent
中删除额外的 router-outlet
。那应该按照您想要的方式进行。我也更新了示例 StackBlitz。
更新 2
如果你想显示某种模式,那么你可以使用ngx-bootstrap
。然后在视频组件的 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']);
}
}
在您的模板中:
<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">×</span>
</button>
</div>
<div class="modal-body">
<p>
Playing Video {{ videoId }}
</p>
</div>
</ng-template>
这应该可以为您完成工作。我重新编辑了示例 StackBlitz。随便看看。
PS: 它不会导航回 /videos
覆盖点击但模式将关闭。这只是您可以自己处理的一种情况。休息我在答案中解释的所有内容。希望这有帮助。
更新 3:
为了在后台显示视频,您必须再次创建 ':id'
路径,使其成为 videos
路径的子路径。但这又会要求您提前显示所有视频,这是您希望避免的情况。
考虑到您最近要求我实现的目标,我已经对 StackBlitz 进行了更新。