Как получить параметр маршрута из ParamMap и назначить его свойству - PullRequest
0 голосов
/ 05 июня 2018

Я использую Angular 6 с RxJs 6.

Я пытаюсь получить значение из paramMap и присвоить его свойству.Маршрут выглядит следующим образом:

{
    path: 'post/:postName',
    component: PostComponent
}

Компонент post в настоящее время выглядит следующим образом:

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { switchMap } from 'rxjs/operators';
import { Observable, of } from 'rxjs';
import * as matter from 'yaml-front-matter';
import { Post } from '../../models/post';

@Component({
  selector: 'blog-post',
  templateUrl: './post.component.html',
  styleUrls: ['./post.component.css'],
  encapsulation: ViewEncapsulation.Emulated
})
export class PostComponent implements OnInit {
  created: Date;
  postName = '';
  markdown = '';
  title = '';
  loading = true;
  author = '';

  constructor(private route: ActivatedRoute) { }

  async ngOnInit () {
    this.route.paramMap.pipe(
      switchMap((params: ParamMap) =>
        of(params.get('postName'))
      )
    ).subscribe(d => this.postName = d);

    const file = await fetch(`/_posts/${this.postName}.md`);
    const text = await file.text();
    const content = text.trim();
    this.parseFrontMatter(content);
  }

  parseFrontMatter (content: string) {
    const frontMatter: Post = matter.loadFront(content);
    this.title = frontMatter.title;
    this.author = frontMatter.author;
    this.created = frontMatter.created;
    this.markdown = frontMatter.__content;
    this.loading = false;
  }
}

В ngOnInit есть код для получения значения из paramMap.Этот код работает, если вы не попытаетесь перенаправить обратно на компонент post с другим параметром.

Это можно наблюдать по адресу Devbin.io .

  1. Перейти на страницу сообщений
  2. Нажмите на единственный пост
  3. Теперь попробуйте перейти на страницу about, которая является просто другим сообщением.
  4. Обратите внимание, что он не будет перенаправлен на страницу About, даже если URL обновлен.

Полный текстисточник может быть найден на GitHub

Вся документация и другие ответы на переполнение стека всегда предполагают, что вы хотите вызвать службу в функции switchMap.Официальная документация: здесь

Мой вопрос: как мне получить параметр маршрута и назначить его свойству и сохранить работу навигации при переходе обратно на тот же маршрут?

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Это потому, что ngOnInit не вызывается при маршрутизации на тот же компонент.В вашем случае / post / Angular-6-Router-How-To-Get-Route-Parameters и / post / About запускают один и тот же компонент: post.component.

Таким образом, чтобы сделать эту работу, вы можете вызватьфункция внутри подписки в paramMap.pipe.

Вы можете сделать что-то вроде этого:

ngOnInit() {
    this.route.paramMap.pipe(
      switchMap((params: ParamMap) =>
        of(params.get('postName'))
      )
    ).subscribe((d) => {
      this.postName = d;
      this.postInit();
    });

  }

  async postInit() {
    const file = await fetch(`/_posts/${this.postName}.md`);
    const text = await file.text();
    const content = text.trim();
    this.parseFrontMatter(content);
  }

  parseFrontMatter(content: string) {
    const frontMatter: Post = matter.loadFront(content);
    this.title = frontMatter.title;
    this.author = frontMatter.author;
    this.created = frontMatter.created;
    this.markdown = frontMatter.__content;
    this.loading = false;
  }
0 голосов
/ 05 июня 2018

Итак, я клонировал репо и исправил проблему.

Замените это:

   async ngOnInit () {
        this.route.paramMap.pipe(
          switchMap((params: ParamMap) =>
            of(params.get('postName'))
          )
        ).subscribe(d => this.postName = d);

        const file = await fetch(`/_posts/${this.postName}.md`);
        const text = await file.text();
        const content = text.trim();
        this.parseFrontMatter(content);
      }

на следующее:

  ngOnInit() {
    this.route.paramMap.pipe(
      switchMap((params: ParamMap) =>
        of(params.get('postName'))
      )
    ).subscribe(d => {
      this.postName = d;

      fetch(`/_posts/${this.postName}.md`)
        .then(data => data.text()
          .then(text => {
            const content = text.trim();
            this.parseFrontMatter(content);
          }));
    });
  }

Объяснение: Вы выбирали сообщения только тогда, когда компонент был инициализирован, так как ваш код выборки файла былза пределами наблюдаемого метода подписки.Я переместился в цепочку обещаний, а затем передал окончательное значение вашей функции parseFrontMatter

...