Sometimes you need to get access to global document.

To simplify unit-testing, Angular provides it through dependency injection:

import { DOCUMENT } from '@angular/common';
import { Inject } from '@angular/core';

  selector: 'my-app',
  template: `<h1>Edit me </h1>`
export class AppComponent {

  constructor(@Inject(DOCUMENT) private document: Document) {
    // Word with document.location, or other things here....

继续阅读 30秒学会 Angular 片段 – Injecting document

Under the hood Angular compiles structural directives into ng-template elements, e.g.:

<!-- This -->
<div *ngFor="let item of [1,2,3]">

<!-- Get expanded into this -->
<ng-template ngFor [ngForOf]="[1,2,3]" let-item="$implicit"></ng-template>

The value passed to *ngFor directive is written using microsyntax. You can learn about it in the docs.

Also check out an interactive tool that shows the expansion by Alexey Zuev



Angular allows us to control the way module preloading is handled.

There are 2 strategies provided by @angular/router: PreloadAllModules and NoPreloading. The latter enabled by default, only preloading lazy modules on demand.

We can override this behavior by providing custom preloading strategy: In the example below we preload all included modules if the connection is good.

import { Observable, of } from 'rxjs';

export class CustomPreloading implements PreloadingStrategy {
  public preload(route: Route, load: () => Observable<any>): Observable<any> {
    return preloadingConnection() ? load() : of(null);

const routing: ModuleWithProviders = RouterModule.forRoot(routes, {
  preloadingStrategy: CustomPreloading

Note that that the example above would not be very efficient for larger apps, as it’ll preload all the modules.

继续阅读 30秒学会 Angular 片段 – Router Custom Preloading

It is possible to add global event listeners in your Components/Directives with HostListener. Angular will take care of unsubscribing once your directive is destroyed.

  selector: '[rightClicker]'
export class ShortcutsDirective {
  doImportantThings() {
    console.log('You pressed right');

继续阅读 30秒学会 Angular 片段 – Global event listeners

It is possible to use SVG tags in your Angular component, to create beautiful graphs and visualizations. There are 3 things you need to know:

  1. When binding an SVG attribute, use attr

    <circle []="x" []="y"></circle>
  2. When creating sub-components, use attribute and not tag selector:

    // Not: <child-component></child-component>
    <g child-component></g>
    @Component({selector: '[child-component]' })
  3. When using SVG tags in sub-components use svg prefix:

    selector: '[child-component]',
    template: `<svg:circle></svg:circle>`

继续阅读 30秒学会 Angular 片段 – SVG

You can create own helper component and use it instead of *ngIf.

  selector: 'loader',
  template: `
    <ng-content *ngIf="!loading else showLoader"></ng-content>
    <ng-template #showLoader>🕚 Wait 10 seconds!</ng-template>
class LoaderComponent {
  @Input() loading: boolean;

For usage example:

<loader [loading]="isLoading">🦊 🦄 🐉</loader>

Note that the content will be eagerly evaluated, e.g. in the snippet below destroy-the-world will be created before the loading even starts:

<loader [loading]="isLoading"><destroy-the-world></destroy-the-world></loader>

继续阅读 30秒学会 Angular 片段 – Loader Component

It’s possible to use @ViewChild (also @ViewChildren and @ContentChild/Children) to query for components of different types using dependency injection.

In the example below we can use @ViewChildren(Base) to get instances of Foo and Bar.

abstract class Base {}

  selector: 'foo',
  providers: [{ provide: Base, useExisting: Foo }]
class Foo extends Base {}

  selector: 'bar',
  providers: [{ provide: Base, useExisting: Bar }]
class Bar extends Base {}

// Now we can require both types of components using Base.
@Component({ template: `<foo></foo><bar></bar>` })
class AppComponent {
  @ViewChildren(Base) components: QueryList<Base>;

继续阅读 30秒学会 Angular 片段 – Getting components of different types with ViewChild

It’s possible to take a template as @Input for a component to customize the render

  template: `
      <ng-container *ngTemplateOutlet="template"></ng-container>
export class SiteMenuComponent  {
  @Input() template: TemplateRef<any>;
<site-menu [template]="menu1"></site-menu>

<ng-template #menu1>
  <div><a href="#">item1</a></div>
  <div><a href="#">item2</a></div>

Note: ng-content should be used for most of the cases and it’s simpler and more declarative.
Only use this approach if you need extra flexibility that can’t be achieved with ng-content.

继续阅读 30秒学会 Angular 片段 – Passing template as an input

Similar to how you can two-way bind [(ngModel)] you can two-way bind custom property on a component, for example [(value)]. To do it use appropriate Input/Output naming:

  selector: 'super-input', 
  template: `...`,
export class AppComponent {
  @Input() value: string;
  @Output() valueChange = new EventEmitter<string>();

Then you can use it as:

<super-input [(value)]="value"></super-input>

继续阅读 30秒学会 Angular 片段 – Two-way binding any property