For testing purposes you might want to inject window.location object in your component.
You can achieve this with custom InjectionToken mechanism provided by Angular.

export const LOCATION_TOKEN = new InjectionToken<Location>('Window location object');

@NgModule({
  providers: [
    { provide: LOCATION_TOKEN, useValue: window.location }
  ]
})
export class SharedModule {}

//...

@Component({
})
export class AppComponent {
  constructor(
    @Inject(LOCATION_TOKEN) public location: Location
  ) {}
}

继续阅读 30秒学会 Angular 片段 – Window Location injection

To act upon swipes, pans, and pinhces as well as the other mobile gestures, you can use hammerjs with HostListener decorator, or an event binding,

npm install hammerjs
@HostListener('swiperight')
public swiperight(): void {
  // Run code when a user swipes to the right
}

继续阅读 30秒学会 Angular 片段 – hammerjs-gestures

In certain cases @Input and @Output properties can be named differently than the actual inputs and outputs.

<div 
  pagination 
  paginationShowFirst="true"
  (paginationPageChanged)="onPageChanged($event)">
</div>
@Directive({ selector: '[pagination]'})
class PaginationComponent {
  @Input('paginationShowFirst') 
  showFirst: boolean = true;

  @Output('paginationPageChanged') 
  pageChanged = new EventEmitter();
}

Note: Use this wisely, see StyleGuide recommedation

翻译自:https://www.30secondsofcode.org/angular/s/renaming-inputs-and-outputs

相关链接

To avoid the expensive operations, we can help Angular to track which items added or removed i.e. customize the default tracking algorithm by providing a trackBy option to NgForOf.

So you can provide your custom trackBy function that will return unique identifier for each iterated item.
For example, some key value of the item. If this key value matches the previous one, then Angular won’t detect changes.

trackBy takes a function that has index and item args.

@Component({
  selector: 'my-app',
  template: `
    <ul>
      <li *ngFor="let item of items; trackBy: trackByFn">{{item.id}}</li>
    </ul>
  `
})
export class AppComponent { 
  trackByFn(index, item) {
    return item.id;
  }
}

If trackBy is given, Angular tracks changes by the return value of the function.

Now when you change the collection, Angular can track which items have been added or removed according to the unique identifier and create/destroy only changed items.

继续阅读 30秒学会 Angular 片段 – trackBy in for loops

By default Angular strips all whitespaces in templates to save bytes. Generally it’s safe.

For rare cases when you need to preserve spaces you can use special ngPreserveWhitespaces attribute:

<div ngPreserveWhitespaces>
             (___()'`;
             /,    /`
       jgs   \\"--\\
</div>

You can also use preserveWhitespaces option on a component.

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

Check out Angular Cheat Sheet or (alternative version) containing lots of useful information condensed in one place.

Also Angular Checklist contains is curated list of common mistakes made when developing Angular applications.

翻译自:https://www.30secondsofcode.org/angular/s/cheat-sheets-and-checklists

相关链接

Here is the way to notify user that there are fields with non-valid values.

markFieldsAsTouched function FormGroup or FormArray as an argument.

function markFieldsAsTouched(form: AbstractControl): void {
  form.markAsTouched({ onlySelf: true });
  if (form instanceof FormArray || form instanceof FormGroup) {
    Object.values(form.controls).forEach(markFieldsAsTouched);
  }
}

继续阅读 30秒学会 Angular 片段 – Mark reactive fields as touched

If you need a custom pipe, before creating one, consider checking out the NGX Pipes package which has 70+ already implemeted custom pipes.

Here are some examples:

<p>{{ date | timeAgo }}</p> 
<!-- Output: "last week" -->

<p>{{ 'foo bar' | ucfirst }}</p>
<!-- Output: "Foo bar" -->

<p>3 {{ 'Painting' | makePluralString: 3 }}</p>
<!-- Output: "3 Paintings" -->

<p>{{ [1, 2, 3, 1, 2, 3] | max }}</p>
<!-- Output: "3" -->

翻译自:https://www.30secondsofcode.org/angular/s/reusing-existing-custom-pipes

相关链接

Every rendered angular component is wrapped in a host element (which is the same as component’s selector).

It is possible to bind properties and attributes of host element using @HostBinding decorators, e.g.

import { Component, HostBinding } from '@angular/core';

@Component({
   selector: 'my-app', 
   template: `
    <div>Use the input below  to select host background-color:</div>
    <input type="color" [(ngModel)]="color"> 
  `,
  styles: [
    `:host { display: block; height: 100px; }`
  ]
})
export class AppComponent {
  @HostBinding('style.background') color = '#ff9900';
}

继续阅读 30秒学会 Angular 片段 – Bind to host properties with host binding