Angular2观察员

时间:2016-02-14 13:29:21

标签: typescript angular

我目前正在尝试将观察者设置为我的应用程序中的三个不同字段,其中每个字段更新时,其他两个字段相应地更新。这是我的代码:

import { Component } from "angular2/core";
import { FORM_DIRECTIVES, CORE_DIRECTIVES, ControlGroup, AbstractControl, FormBuilder } from "angular2/common";

@Component({
    selector: 'temperature-form',
    directives: [FORM_DIRECTIVES, CORE_DIRECTIVES],
    template: `
        <form [ngFormModel]="temperatureForm">
            <div class="input-group">
                <span class="input-group-addon" id="sizing-addon2">°C</span>
                <input type="text" class="form-control" placeholder="Celsius" aria-describedby="sizing-addon2" [ngFormControl]="celsiusField" [(ngModel)]="celsius">
            </div>
            <br />
            <div class="input-group">
                <span class="input-group-addon" id="sizing-addon2">°F</span>
                <input type="text" class="form-control" placeholder="Fahrenheit" aria-describedby="sizing-addon2" [ngFormControl]="fahrenheitField" [(ngModel)]="fahrenheit">
            </div>
            <br />
            <div class="input-group">
                <span class="input-group-addon" id="sizing-addon2">K</span>
                <input type="text" class="form-control" placeholder="Kelvin" aria-describedby="sizing-addon2" [ngFormControl]="kelvinField" [(ngModel)]="kelvin">
            </div>
        </form>
    `
})
export class TemperatureForm {
    temperatureForm: ControlGroup;

    celsius: number;
    fahrenheit: number;
    kelvin: number;

    celsiusField: AbstractControl;
    fahrenheitField: AbstractControl;
    kelvinField: AbstractControl;

    constructor(formBuilder: FormBuilder) {
        this.temperatureForm = formBuilder.group({
            'celsiusField': [''],
            'fahrenheitField': [''],
            'kelvinField': ['']
        });

        this.celsiusField = this.temperatureForm.controls['celsiusField'];
        this.fahrenheitField = this.temperatureForm.controls['fahrenheitField'];
        this.kelvinField = this.temperatureForm.controls['kelvinField'];

        this.celsiusField.valueChanges.subscribe(
            (value: number) => {
                this.fahrenheit = this.celsiusToFahrenheit(value);
                this.kelvin = this.celsiusToKelvin(value);
            }
        );

        this.fahrenheitField.valueChanges.subscribe(
            (value: number) => {
                this.celsius = this.fahrenheitToCelsius(value);
                this.kelvin = this.fahrenheitToKelvin(value);
            }
        );

        this.kelvinField.valueChanges.subscribe(
            (value: number) => {
                this.celsius = this.kelvinToCelsius(value);
                this.fahrenheit = this.kelvinToFahrenheit(value);
            }
        );
    }

    celsiusToFahrenheit(celsius: number): number {
        var fahrenheit: number;

        fahrenheit = celsius * (9 / 5) + 32;

        return fahrenheit;
    }

    celsiusToKelvin(celsius: number): number {
        var kelvin: number;

        kelvin = celsius + 273.15;

        return kelvin;
    }

    fahrenheitToCelsius(fahrenheit: number): number {
        var celsius: number;

        celsius = (fahrenheit - 32) * (5 / 9);

        return celsius;
    }

    fahrenheitToKelvin(fahrenheit: number): number {
        var kelvin: number;

        kelvin = this.celsiusToKelvin(this.fahrenheitToCelsius(fahrenheit));

        return kelvin;
    }

    kelvinToCelsius(kelvin: number): number {
        var celsius: number;

        celsius = kelvin - 273.15;

        return celsius;
    }

    kelvinToFahrenheit(kelvin: number): number {
        var fahrenheit: number;

        fahrenheit = this.celsiusToFahrenheit(this.kelvinToCelsius(kelvin));

        return fahrenheit;
    }
}

然而,问题是,UI不断更新字段,并且值变得像疯了一样。有没有办法解决这个问题?我认为它会因默认值而自动启动。但是,当我更新字段时,其他字段会更新,但是,也会为它们触发valueChange事件,这会无限期地继续。任何解决方案?

1 个答案:

答案 0 :(得分:1)

分区创建双打和双打不应该使用=====进行比较,但Angular并不关心。因此,您需要自己处理。

    this.celsiusField.valueChanges.subscribe(
        (value: number) => {
            var farenheit = this.celsiusToFahrenheit(value);
            if(Math.abs(farentheit - this.farenheit) > 0.0001) {
              this.fahrenheit = farenheit;
            }
            var kelvin = this.celsiusToKelvin(value);
            if(Math.abs(kelvin - this.kelvin) > 0.0001) {
              this.kelvin = kelvin;
            }
        }
    );

与其他功能相似。

这样,当差异低于0.0001时,您就会停止更新(根据您的要求进行调整)。

注意:您可能需要额外的空值检查。