admin管理员组

文章数量:1023054

I am attempting to use Server-Side Rendering in Angular (v4) to allow for better SEO.

Things work as expected until I add resolve on my route. Adding resolve causes HTML title to retain it's initial value when viewing source.

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 './articleponent';
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',
  ponent: 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 '../appponent';

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

@Component({
  selector: 'article-page',
  templateUrl: './articleponent.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.

I am attempting to use Server-Side Rendering in Angular (v4) to allow for better SEO.

Things work as expected until I add resolve on my route. Adding resolve causes HTML title to retain it's initial value when viewing source.

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.ponent';
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',
  ponent: 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.ponent';

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

@Component({
  selector: 'article-page',
  templateUrl: './article.ponent.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.

Share Improve this question asked Oct 4, 2017 at 2:31 Joshua CummingsJoshua Cummings 1453 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

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.

As a side note, this import:

import {
  Observable
} from 'rxjs/Rx';

is an RxJS antipattern. 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.

Attempting to access the client storage caused Angular SSR to omit the generation of source code for my ponent.

Thanks @Adam_P for helping me walk through it!

I am attempting to use Server-Side Rendering in Angular (v4) to allow for better SEO.

Things work as expected until I add resolve on my route. Adding resolve causes HTML title to retain it's initial value when viewing source.

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 './articleponent';
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',
  ponent: 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 '../appponent';

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

@Component({
  selector: 'article-page',
  templateUrl: './articleponent.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.

I am attempting to use Server-Side Rendering in Angular (v4) to allow for better SEO.

Things work as expected until I add resolve on my route. Adding resolve causes HTML title to retain it's initial value when viewing source.

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.ponent';
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',
  ponent: 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.ponent';

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

@Component({
  selector: 'article-page',
  templateUrl: './article.ponent.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.

Share Improve this question asked Oct 4, 2017 at 2:31 Joshua CummingsJoshua Cummings 1453 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

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.

As a side note, this import:

import {
  Observable
} from 'rxjs/Rx';

is an RxJS antipattern. 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.

Attempting to access the client storage caused Angular SSR to omit the generation of source code for my ponent.

Thanks @Adam_P for helping me walk through it!

本文标签: javascriptAngular ServerSide Rendering with Route ResolveStack Overflow