2017-03-02 87 views
3

我有一个关于保存数值的html输入框的指令。当用户将一个数字粘贴到文本框中时,我有一个“清除”数字的指令(去掉逗号,美元符号等)。清洁代码似乎工作正常,但是我的模型没有使用已清理的值进行更新,即使文本框显示了已清理的值。Angular2 - 指令没有更新模型

如何使用新值更新我的模型?

Plnkr here

这里是一个精简例如:

app.ts

@Component(
@Component({ 
    selector : 'my-app', 
    template : ` 
    <div> 
    <br/> 
    <br/> 
    <p>Stack Overflow person - give focus to text box and then lose focus by clicking elsewhere in the screen. <br/>The model is not updated.</p> 
    <br/>Model value: {{ balanceAmount }} 
    <br/> 
    <br/> 
    <input type="text" [(ngModel)]="balanceAmount" myCurrencyFormatter /><br/> 
    </div> 
    `, 
}) 
export class App { 
    name:string; 
    constructor(private mycurpipe: MyCurrencyPipe) { 
    this.balanceAmount = 1234567.89; 
    } 
} 

货币-格式化-Directive.ts

@Directive({ selector: "[myCurrencyFormatter]" }) 
export class MyCurrencyFormatterDirective implements OnInit { 

    private el: any; 

    constructor(
    private elementRef: ElementRef, 
    private currencyPipe: MyCurrencyPipe 
) { 
    this.el = this.elementRef.nativeElement; 

    } 

    ngOnInit() { 
    this.el.value = this.currencyPipe.transform(this.el.value); 
    } 

    @HostListener("focus", ["$event.target.value"]) 
    onFocus(value) { 
    this.el.value = this.currencyPipe.parse(value); // opossite of transform 
    } 

    @HostListener("blur", ["$event.target.value"]) 
    onBlur(value) { 
    this.el.value = this.cleanNumber(value); //"987654" ;//this.currencyPipe.transform(value); 
    } 

    cleanNumber (value: number) { 
    return 8888888; // clean logic goes here, removed for plunk example 
    } 


} 

Plnkr here

+0

你能更新组件中的模型吗? –

+0

是的 - 例如,在我的现实生活应用程序中,用于获取模型的值并执行一些计算并更新模型“TotalValue”。 – ClaytonK

回答

3

您需要为您的模型添加Emitter。这是在Angular 2中实现2路绑定的方式。请看一下@Output() ngModelChange = new EventEmitter();行,以及我如何使用此变量将更改发送给调用者。

import { Directive, HostListener, ElementRef, OnInit, EventEmitter, Output } from "@angular/core"; 
import { MyCurrencyPipe } from "./my-currency.pipe"; 

@Directive({ selector: "[myCurrencyFormatter]" }) 
export class MyCurrencyFormatterDirective implements OnInit { 

    private el: any; 
    @Output() ngModelChange = new EventEmitter(); 

    constructor(
    private elementRef: ElementRef, 
    private currencyPipe: MyCurrencyPipe 
) { 
    this.el = this.elementRef.nativeElement; 

    } 

    ngOnInit() { 
    this.el.value = this.currencyPipe.transform(this.el.value); 
    } 

    @HostListener("focus", ["$event.target.value"]) 
    onFocus(value) { 
    this.el.value = this.currencyPipe.parse(value); // oposite of transform 
    this.ngModelChange.emit(this.el.value); 
    } 

    @HostListener("blur", ["$event.target.value"]) 
    onBlur(value) { 
    this.el.value = this.cleanNumber(value); //"987654" ;//this.currencyPipe.transform(value); 
    this.ngModelChange.emit(this.el.value); 
    } 

    cleanNumber (value: number) { 
    return 8888888; 
    } 

} 
+0

谢谢。要添加,eventEmitter必须被称为'ngModelChange'。如果它是其他的东西,那么你必须专门为使用attribute指令的元素添加一个监听器。例如'' – ClaytonK

+0

这是否使用ReactiveForms工作?我添加了一个类似于你的例子的输出EventEmitter,然后调用'this.ngModelChange.emit(value)',但它似乎不工作,所以我假设这只适用于模板驱动窗体?如果您有兴趣,我在此发布了一个问题:http://stackoverflow.com/q/43380390/1148107其中包含一名运动员 – mtpultz