2015-12-23 7 views
5

Ich habe ein DTO-Objekt, das einen Date-Parameter hat. Ich wickle dieses Dto in ein Ansichtsmodellobjekt ein, dessen Eigenschaften ich dann aus meiner Sicht an ein Etikett binde.Warum geht angularjs Digest in Endlosschleife mit Datum Getter-Funktion

<label class="form-control">{{controller.ViewModel.Date}}</label> 

Im View-Modell habe ich also einen Getter. (Ich bin mit Typoskript)

public get Date(): Date { 
    return new Date(Date.parse(this.dto.Date)); 
    //return moment(this.dto.Date).toDate(); 
} 

das emittierte JavaScript:

Object.defineProperty(ViewModel.prototype, "Date", { 
    get: function() { 
     return new Date(Date.parse(this.dto.Date)); 
    }, 
    enumerable: true, 
    configurable: true 
}); 

Ich glaube, dass der Grund, weil ich ein neues Date in dem Getter erschaffe und Winkel denkt, dass dies bedeutet, die Daten sind immer neu und es erhält das Datum, bis sich das Modell stabilisiert und somit eine Endlosschleife verursacht.

Warum funktioniert das eckig?
Warum ruft es den Getter immer wieder an, was ist falsch daran, es nur einmal anzurufen?
Kann ich Angular angeben, um den Getter nur einmal aufzurufen und den angegebenen Wert zu akzeptieren?

+0

Welche Version von eckigen verwenden Sie? – SpykeBytes

+0

eckig wird aufeinanderfolgende Verdaus laufen, bis sich das Ergebnis aller Beobachter stabilisiert. Hier wird jedes Mal, wenn Ihr Beobachter ein anderes Objekt zurückgibt, die Endlosschleife erzeugt. Manchmal können Sie dies umgehen, indem Sie toString() für das Ergebnis verwenden, wenn Sie von einer Vorlage aufgerufen werden. Beispiel: '{{controller.ViewModel.Date.toString()}}' – BiAiB

+2

Warum speichern Sie das Ergebnis der Funktion nicht in einer $ scope-Variablen und verwenden Sie diese dann im HTML, anstatt direkt mit der Funktion –

Antwort

2

Wenn Sie eine Version mit ausreichend hoher Auflösung verwenden, können Sie eine einmalige Bindung versuchen. Folgen Sie den Anweisungen hier: https://docs.angularjs.org/guide/expression#one-time-binding

Sie sind im Grunde mit Ihrer Annahme richtig, dass eckig denkt, dass die Daten immer neu sind. Sie ändern den Wert mit der Auswertung in Ihrem Getter und eckigen unsauber überprüfen und wacht löst einen weiteren Digest aus.

Können Sie auch versuchen, das Datum im Voraus zu analysieren?

+0

zu verknüpfen Ich habe versucht, meine Operationen so kantig zu verbergen, aber ich bekomme das gleiche Ergebnis. public get TxDate(): Datum { let dtoDate = Moment (this.dto.TxDate) .toDate(); if (this._txDate === undefined || this._txDate === null) this._txDate = dtoDate; if (dtoDate.getFullYear()! = This._txDate.getFullYear() || dtoDate.getMonth()! = This._txDate.getMonth() || dtoDate.getDate()! = This._txDate.getDate()) { this._txDate = dtoDate; } Rückgabe this._txDate; } – John

2

fand ich einen Weg rund um das wie folgt aus:

nur das Typoskript veröffentlichen, wie es besser lesbar ist:

public DisplayDate: string = new Date(Date.parse(this.dto.TxDate)).toLocaleDateString(); 
    public get TxDate(): Date { 

     let txDate = new Date(Date.parse(this.dto.TxDate)); 
     if (this._txDate === null && this._txDate != txDate) 
      this._txDate = txDate; 
     return this._txDate; 
    } 
    public set TxDate(value: Date) { 
     this.dto.TxDate = value.toISOString(); 
     this._txDate = value; 
     this.DisplayDate = this._txDate.toLocaleDateString(); 
    } 
    private _txDate: Date = null; 

Dies scheint mir zu geben, was ich brauche. Das Anzeigedatum ist an eine sichtbare Beschriftung gebunden, so dass ich das gewünschte Anzeigeformat erhalten kann und das TxDate an ein verborgenes Formular-Datumsauswahlsteuerelement gebunden ist. Auf diese Weise scheint alles zu funktionieren. Und ich kann mein Dto-Datum im ISO8601-Format behalten.

Verwandte Themen