在Angular中基于路由动态添加元描述

Kel*_*len 40 typescript angular-ui-router angular

我正在使用Angular 5建立一个小型宣传册类型的网站.到目前为止,我已经设置了路由,页面标题会根据激活的路由动态变化.我使用此博客上的说明进行了此操作:https://toddmotto.com/dynamic-page-titles-angular-2-router-events

我目前正在app.module.ts中存储我的路线和标题:

imports: [
    BrowserModule,
    RouterModule.forRoot([
      { 
        path: '', 
        component: HomeComponent,
        data: {
          title: 'Home'
        }
      },
      { 
        path: 'about', 
        component: AboutComponent,
        data: {
          title: 'About'
        } 
      },
      { 
        path: 'products-and-services', 
        component: ProductsServicesComponent,
        data: {
          title: 'Products & Services'
        }  
      },
      { 
        path: 'world-class-laundry', 
        component: LaundryComponent,
        data: {
          title: 'World Class Laundry'
        }  
      },
      { 
        path: 'contact', 
        component: ContactComponent,
        data: {
          title: 'Contact'
        }  
      },
      { 
        path: '**', 
        component: NotFoundComponent,
        data: {
          title: 'Page Not Found'
        }  
      }
    ])
  ],
Run Code Online (Sandbox Code Playgroud)

我想在那里存储我的元描述,如果添加它们data:就足够了.

我正在使用以下代码提取该标题数据,该代码在上面的博客链接中注明:

ngOnInit() {
    this.router.events
      .filter((event) => event instanceof NavigationEnd)
      .map(() => this.activatedRoute)
      .map((route) => {
        while (route.firstChild) route = route.firstChild;
        return route;
      })
      .filter((route) => route.outlet === 'primary')
      .mergeMap((route) => route.data)
      .subscribe((event) => {
        this.titleService.setTitle(event['title']);
      });
  }
Run Code Online (Sandbox Code Playgroud)

所以我的问题是,有没有办法使用相同的方法动态设置元描述?如果有一种方法来组合页面标题和元描述功能,那将是理想的.

我的角色训练非常有限,所以这可能是一个不成熟的问题.我更像是一个设计师/ css/html那种人.

Oka*_*kan 47

首先创建一个SEOService或类似下面的东西:

import {Injectable} from '@angular/core'; 
import { Meta, Title } from '@angular/platform-browser';

@Injectable()
export class SEOService {
  constructor(private title: Title, private meta: Meta) { }


  updateTitle(title: string) {
    this.title.setTitle(title);
  }

  updateOgUrl(url: string) {
    this.meta.updateTag({ name: 'og:url', content: url })
  }

  updateDescription(desc: string) {
    this.meta.updateTag({ name: 'description', content: desc })
  }
Run Code Online (Sandbox Code Playgroud)

组件中注入SEOService后,在OnInit方法中设置元标记和标题

ngOnInit() {
this.router.events
  .filter((event) => event instanceof NavigationEnd)
  .map(() => this.activatedRoute)
  .map((route) => {
    while (route.firstChild) route = route.firstChild;
    return route;
  })
  .filter((route) => route.outlet === 'primary')
  .mergeMap((route) => route.data)
  .subscribe((event) => {
    this._seoService.updateTitle(event['title']);
    this._seoService.updateOgUrl(event['ogUrl']);
    //Updating Description tag dynamically with title
    this._seoService.updateDescription(event['title'] + event['description'])
  }); 
}
Run Code Online (Sandbox Code Playgroud)

编辑:对于使用管道运算符的RxJs 6+

ngOnInit() {
    this.router.events.pipe(
       filter((event) => event instanceof NavigationEnd),
       map(() => this.activatedRoute),
       map((route) => {
         while (route.firstChild) route = route.firstChild;
         return route;
       }),
       filter((route) => route.outlet === 'primary'),
       mergeMap((route) => route.data)
      )
      .subscribe((event) => {
        this._seoService.updateTitle(event['title']);
        this._seoService.updateOgUrl(event['ogUrl']);
        //Updating Description tag dynamically with title
        this._seoService.updateDescription(event['title'] + event['description'])
      }); 
    }
Run Code Online (Sandbox Code Playgroud)

然后配置您的路线,如

      { 
        path: 'about', 
        component: AboutComponent,
        data: {
          title: 'About',
          description:'Description Meta Tag Content',
          ogUrl: 'your og url'
        } 
      },
Run Code Online (Sandbox Code Playgroud)

恕我直言这是一个处理元标记的明确方法.您可以更轻松地更新Facebook和Twitter特定标签.

  • 在您的app.module.ts提供程序部分中导入SEOService。然后在您设置元标记和标题的组件中,将SEOService注入类似`constructor(public _seoService:SEOService)`的构造函数中 (3认同)
  • 奥哈恩全都欢呼!似乎像魅力一样工作.谢谢! (2认同)
  • 还要导入以下内容:`import 'rxjs/add/operator/filter'; 导入 'rxjs/add/operator/map'; 导入'rxjs/add/operator/mergeMap';` (2认同)

小智 18

用于在路由更改时动态设置标题的 Angular 6+ 和 RxJS 6+ 解决方案

如果/当您升级到 Angular 6 时,这就是解决方案。

这项服务将:

  • 更新路线更改的元标题。
  • 出于您想要的任何原因覆盖标题的选项。

将您的 SEO/meta 服务创建/更改为以下内容。

import { Injectable } from '@angular/core';
import { Title, Meta } from '@angular/platform-browser';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';

@Injectable({
    providedIn: 'root'
})
export class MetaService {
    constructor(
        private titleService: Title,
        private meta: Meta,
        private router: Router,
        private activatedRoute: ActivatedRoute
    ) { }

    updateMetaInfo(content, author, category) {
        this.meta.updateTag({ name: 'description', content: content });
        this.meta.updateTag({ name: 'author', content: author });
        this.meta.updateTag({ name: 'keywords', content: category });
    }

    updateTitle(title?: string) {
        if (!title) {
            this.router.events
                .pipe(
                    filter((event) => event instanceof NavigationEnd),
                    map(() => this.activatedRoute),
                    map((route) => {
                        while (route.firstChild) { route = route.firstChild; }
                        return route;
                    }),
                    filter((route) => route.outlet === 'primary'),
                    mergeMap((route) => route.data)).subscribe((event) => {
                        this.titleService.setTitle(event['title'] + ' | Site name');
                    });
        } else {
            this.titleService.setTitle(title + ' | Site name');
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

导入您的服务并在构造函数中调用它。

app.component.ts

constructor(private meta: MetaService) {
    this.meta.updateTitle();
}
Run Code Online (Sandbox Code Playgroud)

这仍然需要像这样格式化路由。

路由文件.ts

{ 
    path: 'about', 
    component: AboutComponent,
    data: {
      title: 'About',
      description:'Description Meta Tag Content'
    } 
  },
Run Code Online (Sandbox Code Playgroud)

希望这对您和其他希望在 Angular 6 中动态更新标题/元的人有所帮助。


Est*_*ask 7

Title并且Meta是Angular 4中引入的提供程序,并且应该在服务器端和客户端端执行此操作.

要创建或更新title标记和description元标记,它是:

import { Meta, Title } from '@angular/platform-browser';

...

constructor(public meta: Meta, public title: Title, ...) { ... }

...

this.meta.updateTag({ name: 'description', content: description }); 
this.title.setTitle(title);
Run Code Online (Sandbox Code Playgroud)

  • 我会试试这个,如果这有效,那么这就是答案 (2认同)