2016-06-28 16 views
11

Sprzątam mój projekt kątowy2 i z wielu powodów postanowiłem zacząć od nasienia. This one.NG2: angular2-webpack-starter - jaki jest cel HMR?

To nasienie używa HMR, ale nie do końca rozumiem, jaki jest tego cel.

Na początku myślałem, że HMR dotyczy dynamicznego ładowania i zastępowania komponentu podczas działania aplikacji internetowej.

Ale odkąd spuściłem wzrok na app.service.ts, zgubiłem się. Oto kod tej usługi:

import { Injectable } from '@angular/core'; 
import { HmrState } from 'angular2-hmr'; 

@Injectable() 
export class AppState { 
    // @HmrState() is used by HMR to track the state of any object during a hot module replacement 
    @HmrState() _state = { }; 

    constructor() { 

    } 

    // already return a clone of the current state 
    get state() { 
    return this._state = this._clone(this._state); 
    } 
    // never allow mutation 
    set state(value) { 
    throw new Error('do not mutate the `.state` directly'); 
    } 


    get(prop?: any) { 
    // use our state getter for the clone 
    const state = this.state; 
    return state[prop] || state; 
    } 

    set(prop: string, value: any) { 
    // internally mutate our state 
    return this._state[prop] = value; 
    } 


    _clone(object) { 
    // simple object clone 
    return JSON.parse(JSON.stringify(object)); 
    } 
} 

Myślałem, że ta usługa po prostu zapewnia miejsce do przechowywania niektórych danych. W końcu to tylko przykład.

Ale ta linia mnie zmyliła: @HmrState() _state = { };. Czy ta usługa używa HMR do zarządzania danymi, którymi możemy zarządzać za pomocą this.appState.set('value', value); (to jest z HomeComponent), tak jak mały sklep Redux (bez akcji, dyspozytora, blabla)?

Jaki jest cel dekoratora @HmrState() tutaj?

Dzięki.

Odpowiedz

19

Kiedy po raz pierwszy zobaczyłem angular2-hmr, byłem również zaskoczony. Myślałem, że to coś w rodzaju wymiany na gorąco, ale tak naprawdę to nie jest jedna. Przynajmniej z tego, co widzę, kiedy go używam.

Wygląda na to, że zawsze ponownie ładuje aplikację, niezależnie od typu zmiany. Może jednak przywrócić stan zamienionych obiektów. Intencją @HmrState() jest przywrócenie stanu komponentu po ponownym załadowaniu aplikacji.

Rzućmy okiem na mały przykład. Mamy formę z wejściem, który jest związany (z ngModel lub formControl) własności jakiegoś składnika:

@Component({ 
    template: ` 
    <input [(ngModel)]="inputValue" /> 
    <button (click)="click()">Click me</button> 
    ` 
}) 
export class MyComponent { 

    public inputValue: string; 

    public click() { 
    console.log(this.inputValue); 
    } 

} 

my na pewnej wartości, np "test123" i kliknij przycisk. To działa.

Potem nagle zdajemy sobie sprawę: brakuje opisu dziennika. Więc idziemy do naszego kodu i dodać go:

@Component({ 
    template: ` 
    <input [(ngModel)]="inputValue" /> 
    <button (click)="click()">Click me</button> 
    ` 
}) 
export class MyComponent { 

    inputValue: string; 

    public click() { 
    console.log('inputValue:', this.inputValue); 
    } 

} 

Następnie kod komponentu jest zmieniony, HMR zastępuje go i zdajemy sobie sprawę, że inputValue jest stracone.

Aby przywrócić wartość podczas procesu HMR, angular2-hmr potrzebuje informacji o stanie obiektu przed jego wymazaniem. Tutaj wchodzi do gry @HmrState(): wskazuje na stan, który powinien zostać przywrócony. Innymi słowy, aby pierwszy urywek kodu pracę z HMR dodaje powinny odbywać się:

@Component({ 
    template: ` 
    <input [(ngModel)]="state.inputValue" /> 
    <button (click)="click()">Click me</button> 
    ` 
}) 
export class MyComponent { 

    @HmrState() public state = { 
    inputValue: '' 
    } 

    public click() { 
    console.log(this.state.inputValue); 
    } 

} 

Państwo jest obecnie znany z procesorem HMR i można go użyć w celu przywrócenia stanu naszą wartość. Teraz, gdy zmieniamy kod komponentu na:

@Component({ 
    template: ` 
    <input [(ngModel)]="state.inputValue" /> 
    <button (click)="click()">Click me</button> 
    ` 
}) 
export class MyComponent { 

    @HmrState() public state = { 
    inputValue: '' 
    } 

    public click() { 
    console.log('inputValue:', this.state.inputValue); 
    } 

} 

to magicznie ponownie ładuje naszą aplikację i wartość inputValue zostaje zachowana.