2016-06-28 58 views
11

我正在清理我的angular2项目,由于很多原因,我决定从种子开始。 This oneNG2:angular2-webpack-starter - HMR的目的是什么?

该种子使用HMR,但我不完全明白这是什么目的。

开始的时候,我一直在想HMR是关于动态加载和 在Web应用程序运行时替换组件的。

但是因为我已经把目光投向了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()的意图是在应用程序重新加载时恢复组件的状态。

我们来看一个小例子。我们有这势必(与ngModelformControl)一些组件的属性的输入的形式:

@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()发挥作用:它指出应该恢复的状态。换句话说,以与HMR第一代码片段工作,下面要做到:

@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的值。