简体   繁体   English

带有路由解析的角度服务器端渲染

[英]Angular Server-Side Rendering with Route Resolve

I am attempting to use Server-Side Rendering in Angular (v4) to allow for better SEO. 我试图在Angular(v4)中使用服务器端渲染,以实现更好的SEO。

Things work as expected until I add resolve on my route. 事情一直按预期进行,直到我在路线上添加resolve为止。 Adding resolve causes HTML title to retain it's initial value when viewing source. 添加resolve导致HTML title在查看源代码时保留其初始值。

My Module: 我的模块:

import {
  Injectable,
  ModuleWithProviders,
  NgModule
} from '@angular/core';
import {
  ActivatedRouteSnapshot,
  Resolve,
  Router,
  RouterModule,
  RouterStateSnapshot
} from '@angular/router';
import {
  Observable
} from 'rxjs/Rx';

import {
  ArticleComponent
} from './article.component';
import {
  Article,
  ArticlesService,
  UserService,
  SharedModule
} from '../shared';

@Injectable()
export class ArticleResolver implements Resolve < Article > {
  constructor(
    private articlesService: ArticlesService,
    private router: Router,
    private userService: UserService
  ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): any {
    return this.articlesService.get(route.params['slug'])
      .catch((err) => this.router.navigateByUrl('/'));
  }
}

const articleRouting: ModuleWithProviders = RouterModule.forChild([{
  path: 'article/:slug',
  component: ArticleComponent,
  resolve: {
     article: ArticleResolver
  },
  data: {
    preload: true
  }
}]);

@NgModule({
  imports: [
    articleRouting,
    SharedModule
  ],
  declarations: [
    ArticleComponent
  ],

  providers: [
    ArticleResolver
  ]
}) export class ArticleModule {}

My Component: 我的组件:

import {
  Component,
  OnInit
} from '@angular/core';
import {
  ActivatedRoute,
  Router,
} from '@angular/router';
import {
  Title,
  Meta
} from '@angular/platform-browser';

import {
  AppComponent
} from '../app.component';

import {
  Article,
} from '../shared';

@Component({
  selector: 'article-page',
  templateUrl: './article.component.html'
})
export class ArticleComponent implements OnInit {
  article: Article;

  constructor(
    private route: ActivatedRoute,
    private meta: Meta,
    private title: Title
  ) {}

  ngOnInit() {
    this.route.data.subscribe(
      (data: {
        article: Article
      }) => {
        this.article = data.article;
      }
    );
    this.title.setTitle(this.article.title);
  }
}

I am new to Angular SSR so any guidance is greatly appreciated. 我是Angular SSR的新手,因此非常感谢任何指导。

Instead of subscribing to route data, retrieve your results from the snapshot like this: 无需订阅路由数据,而是从快照中检索结果,如下所示:

this.route.snapshot.data['article']

You also might need to register ArticlesService in your providers for the module. 您可能还需要在模块的providers注册ArticlesService

As a side note, this import: 作为附带说明,此导入:

import {
  Observable
} from 'rxjs/Rx';

is an RxJS antipattern. 是RxJS反模式。 Please use the following import instead: 请改用以下导入:

import {Observable} from 'rxjs/Observable';

I found that my primary service was referencing a secondary service that was attempting to return an authentication token from window.localStorage . 我发现我的主要服务引用了一个辅助服务,该服务试图从window.localStorage返回身份验证令牌。

Attempting to access the client storage caused Angular SSR to omit the generation of source code for my component. 尝试访问客户端存储导致Angular SSR省略了我组件的源代码生成。

Thanks @Adam_P for helping me walk through it! 感谢@Adam_P帮助我完成它!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM