Как использовать pushState на угловой? - PullRequest
0 голосов
/ 23 ноября 2018

Я хочу изменить URL, не перезагружая страницу.Я использую сервис определения местоположения как:

this.location.replaceState(`mynewurl`);

Когда я возвращаюсь назад, история не хороша.Я нашел решение html5 pushState.

Я спрашиваю, не существует ли такой службы, как Location, которая обрабатывает pushState для угловых

1 Ответ

0 голосов
/ 23 ноября 2018

Вы можете выполнить следующие шаги для достижения этого:

  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 }
  ] },
];
Добавьте RouterModule.forRoot(routes) к массиву imports вашего @NgModule:
@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.Используйте его для отображения соответствующего видео:
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' }
];

И избавьтесь от дополнительных router-outlet из VideosComponent.Это должно быть так, как вы хотите.Я также обновил Sample StackBlitz.

UPDATE 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">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <p>
      Playing Video {{ videoId }}
    </p>
  </div>
</ng-template>

Это должно сработать за вас.Я отредактировал Sample StackBlitz.Просто посмотрите.

PS: Он не вернется к /videos при наложении, но модальное закроется.Это только один случай, который вы можете решить самостоятельно.Отдыхайте все, что я объяснил в ответе.Надеюсь, это поможет.

ОБНОВЛЕНИЕ 3:

Для отображения видео в фоновом режиме вам придется снова сделать путь ':id', дочерним по отношению к пути videos.Но тогда это снова потребует от вас показа всех видео авансом, чего вы хотели избежать.

В любом случае, я обновил StackBlitz, учитывая то, что вы недавно просили меня достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...