2016-06-28 2 views
11

Я очищаю свой проект angular2 и по многим причинам, я решил начать с семени. This one.NG2: angular2-webpack-starter - какова цель HMR?

Это семя использует HMR, но я не совсем понимаю, в чем его цель.

В начале я думал, что HMR был о динамической загрузке и заменяющий компонент во время работы веб-приложения.

Но поскольку я посмотрел на app.service.ts, я потерялся. Вот код услуг:

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)); 
    } 
} 

Я думал, что служба просто предоставляет пространство для хранения некоторых данных. В конце концов, это всего лишь пример.

Но эта линия меня смутила: @HmrState() _state = { };. Эта служба использует HMR для управления данными, которыми мы можем управлять с помощью this.appState.set('value', value); (это из HomeComponent), как маленький магазин Redux (без действий, диспетчер, blabla)?

Какова цель декоратора @HmrState() здесь?

Спасибо.

ответ

19

Когда я впервые посмотрел на angular2-hmr, я тоже был удивлен. Я думал, что это что-то вроде горячей замены, но на самом деле это не так. По крайней мере, из того, что я вижу, когда использую его.

Похоже, он всегда перезагружает приложение независимо от типа изменения. Однако он может восстановить состояние обмениваемых объектов. Целью @HmrState() является восстановление состояния компонента при перезагрузке приложения.

Давайте рассмотрим небольшой пример. Мы имеем форму с входом, который связан (с ngModel или formControl) имуществу какого-то компонента:

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

    public inputValue: string; 

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

} 

мы вводим в некотором значении, например, 'test123' и нажмите кнопку. Оно работает.

Затем мы осознаем: описание журнала отсутствует. Поэтому мы идем в наш код и добавить его:

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

    inputValue: string; 

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

} 

Затем код компонента изменен, HMR заменяет его, и мы понимаем, что inputValue теряется.

Для восстановления значения во время процесса HMR angular2-hmr нуждается в некоторой информации о состоянии объекта до его уничтожения. Здесь вступает в игру @HmrState(): он указывает на состояние, которое должно быть восстановлено. Другими словами, чтобы сделать первый фрагмент кода работы с ГМР следующее должно быть сделано:

@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); 
    } 

} 

Государство теперь известно к процессору HMR, и он может использовать государство, чтобы восстановить нашу ценность. Теперь, когда мы изменим код компонента для:

@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); 
    } 

} 

магически перезагружает наше приложение и сохраняется ценность InputValue в.