2017-03-02 61 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