@angular-package/change-detection

Package to improve application performance.

Stats

stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
67Jun 1, 2021Nov 20, 2017Minified + gzip package size for @angular-package/change-detection in KB

Readme

change-detection

Decorator to improve application performance by setting initially change detection component state to Detached and detect changes on indicated properties on set.

import { ApChangeDetection } from '@angular-package/change-detection';
@ApChangeDetection<T>(properties: ApChangeDetectionProperties, options?: ApChangeDetectionOptions): Function
name Type Description
properties ApChangeDetectionProperties {[index:string]:boolean} Name of component property with value true is sensitive for detection. E.g. {firstname: true, surname: false}
options? ApChangeDetectionOptions { detach?: string; detect?: string; properties?: string; reattach?: string;} Method or property name that is accessible directly in component under this name. E.g. {detach: '__detach', detect: '_detect', reattach: undefined}

Pros(+):

  • Treeshake bundle with Rollup - module bundler for JavaScript.
  • AOT (Ahead Of Time Compilation) package: faster rendering, fewer asynchronous requests, smaller Angular framework download size, detect template errors earlier, better security.
  • MIT License: it can be used commercially.
  • Component property detection sets initially its change detection state, where false means Detached.
  • Default component property detection is controlled by component property _properties: ApChangeDetectionProperties.
  • Some properties and methods names are configurable.
  • Uses ApChangeDetectorClass to handle change detection.

Cons(-):

  • Cannot indicate new properties dynamically. (New property can be added.)
  • Need to inject ChangeDetectorRef instance as usually.
  • There are no tests. (There are tests.)

Important!

  • There are two property that aren't configurable by name: changeDetector, detection.
  • Set ChangeDetectionStrategy.OnPush in component.
  • Inject ChangeDetectorRef to component.
  • Initialize detection by setting detection: boolean property component with default value as false.
  • For better understanding what you can do in component extend it with ApChangeDetectorAClass or ApChangeDetection interface.


Demonstration

Available

Live demonstration

Demo available inside repository.

Installation

Install @angular-package/change-detection package with command:

npm i --save @angular-package/change-detection@1.0.0

Install peerDependencies:

npm i --save @angular-package/core@1.0.1

Properties

Properties added directly to component.

Name / Linked Type / Default value Description
_changeDetector ApChangeDetectorClass<T> ApChangeDetectorClass instance.
changeDetector [_changeDetector] ApChangeDetectorClass<T> / ApChangeDetectorClass<T>(this, Object.assign({}, properties)) Wrapper for _changeDetector property. Property is linked to _changeDetector.
detection [changeDetector.detection] boolean / false Whether detection is on true or off false. Property is linked to changeDetector.detection.
_properties [changeDetector.properties] ApChangeDetectionProperties / {} Detect changes when specified property name is true e.g. { firstname: true }. Property is linked to changeDetector.properties.

Methods

Methods directly added to component.

_detach

Detaches component change detector from the change detector tree.

_detach(): void;

_detect

Detect changes in specified component, and also conditionally by providing property name.

_detect(property?: string): void;

_reattach

Reattach component change detector to the change detector tree and sets property detection to true.

_reattach(): void;

Usage

1. Add to any component of your application ApChangeDetection decorator like in component.ts below.

// component.ts
// external
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core';

// @angular-package
import { ApChangeDetection } from '@angular-package/change-detection';
import { ApChangeDetectorClass } from '@angular-package/change-detection/change-detector';
import { ApChangeDetector, ApChangeDetectionProperties } from '@angular-package/change-detection/interface';

// internal
import { AddressInterface } from './interface';

export const OPTIONS: ApChangeDetectionOptions = {
  properties: '_properties'
};

export const PROPERTIES = {
  name: false,
  surname: true
};

@Component({
  preserveWhitespaces: false,
  changeDetection: ChangeDetectionStrategy.OnPush,
  selector: 'app-changedetection-component',
  templateUrl: './component.html',
  styleUrls: [ 'component.scss' ]
})
@ApChangeDetection<ChangeDetectionComponent>(PROPERTIES, OPTIONS)
export
  class ChangeDetectionComponent
  implements ApChangeDetector<ChangeDetectionComponent> {

  // Whether change detection is active or not. If false, change detection status is set to `Detached`.
  // If true, change detection status is set to `CheckOnce` because of OnPush.
  public detection = false; // <--- Required, initialize detection with specified value true or false.
  public changeDetector: ApChangeDetectorClass<ChangeDetectionComponent>; // ChangeDetector instance.
  public _properties: ApChangeDetectionProperties; // --- Not required. Properties that will be detected when true.

  public _address: AddressInterface;
  @Input('address')
  set address(address: AddressInterface) {
    this._address = address;
  }
  get address(): AddressInterface {
    return this._address;
  }

  _name: string;
  @Input('name')
  set name(name: string) {
    this._name = name;
  }
  get name(): string {
    return this._name;
  }

  @Input('surname') surname;

  public _detach(): void { }
  public _detect(): void { }
  public _reattach(): void { }

  constructor(public c: ChangeDetectorRef) { }

  update($event) {
    this._detect();
  }
}

2. Template file component.html of component above displays name and surname, and add some inputs to check how it works.

<!-- component.html -->
<h1>ChangeDetectionComponent</h1>
{{detection}}
<div>
  <!-- [value]="true" (change)="update($event)"  -->
  <mat-checkbox name="detection" [(ngModel)]="detection">
    Component change detection
    <small>Means Detached when false</small>
  </mat-checkbox>
  <div>
    <mat-form-field>
      <input matInput placeholder="Name" name="name" [(ngModel)]="name" />
    </mat-form-field>
    <mat-checkbox (change)="update($event)" [(ngModel)]="_properties.name" *ngIf="detection === false" >
      Detect changes in property
      <small>When component is detached</small>
    </mat-checkbox>
  </div>
  <div>
    <mat-form-field>
      <input matInput placeholder="Surname" name="surname" [(ngModel)]="surname" />
    </mat-form-field>
    <mat-checkbox (change)="update($event)" [(ngModel)]="_properties.surname" *ngIf="detection === false">
      Detect changes in property.
      <small>When component is detached</small>
    </mat-checkbox>
  </div>
  <p>
    {{name}} {{surname}}
  </p>
</div>

3. Add newly created component to AppModule.

// external.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

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

@NgModule({
  declarations: [
    AppComponent,
    ChangeDetectionComponent // <-- Add component above to primary module.
  ],
  imports: [
    BrowserModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

4. Displays component with ApChangeDetection decorator.

<!-- app.component.html -->
<app-changedetection-component [address]="{city: 'Web', street: 'HTML'}" [name]="'Angular'" [surname]="'Package'"></app-changedetection-component>
<app-changedetection-component [address]="{city: 'Component', street: 'Decorator'}" [name]="'Change Detection'" [surname]="'Feature'"></app-changedetection-component>
<app-changedetection-component [address]="{city: 'Poznań', street: 'Głuszyna'}" [name]="'Ścibor'" [surname]="'Rudnicki'"></app-changedetection-component>
<app-changedetection-component [address]="{city: 'Web', street: 'HTML'}" [name]="'Angular'" [surname]="'Package'"></app-changedetection-component>
<app-changedetection-component [address]="{city: 'Component', street: 'Decorator'}" [name]="'Change Detection'" [surname]="'Feature'"></app-changedetection-component>

Scripts

Clone repository:

git clone https://github.com/angular-package/angular-package.git

Go to just created folder:

cd angular-package/packages/change-detection

To build a clean package, means before that script removes node_modules, dist folder and install dependencies:

npm run clean:start

To build a package:

npm start

To run karma tests:

npm test

GIT

Commit

Versioning

Semantic Versioning 2.0.0

Given a version number MAJOR.MINOR.PATCH, increment the:

  • MAJOR version when you make incompatible API changes,
  • MINOR version when you add functionality in a backwards-compatible manner, and
  • PATCH version when you make backwards-compatible bug fixes.

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

FAQ How should I deal with revisions in the 0.y.z initial development phase?

The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release.

How do I know when to release 1.0.0?

If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should probably already be 1.0.0.

License

MIT © angular-package (license)

If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.