2015-12-23 10 views
5

Ho un oggetto DTO che ha un parametro Date. Sto avvolgendo questo Dto in un oggetto del modello di vista le cui proprietà sono quindi vincolanti per la mia vista su un'etichetta.Perché angularjs Digest va in loop infinito con funzione getter di data

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

Nel modello di vista ho un getter quindi. (Sto usando dattiloscritto)

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

il emessa JavaScript:

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

Credo che la ragione per cui sto creando una nuova data nel getter e angolare pensa che questo significa sono sempre nuove date e continua a ricevere la data fino a quando il modello si stabilizza, causando così un loop infinito.

Perché è angolare farlo?
Perché continua a chiamare il getter più e più volte, cosa c'è di sbagliato nel chiamarlo una volta sola?
Posso dire angolare per chiamare solo il getter una volta e accettare il valore è dato?

+0

Quale versione di angolare stai usando? – SpykeBytes

+0

angolare eseguirà sequenze consecutive fino a quando il risultato di tutti gli osservatori si stabilizzerà. Qui, ogni volta che l'osservatore restituisce un oggetto diverso, generando così il loop infinito. A volte è possibile aggirare questo usando toString() sul risultato quando viene chiamato da un modello. Esempio: '{{controller.ViewModel.Date.toString()}}' – BiAiB

+2

Perché non si memorizza il risultato della funzione in una variabile $ scope e quindi si utilizza l'HTML, anziché il collegamento diretto alla funzione –

risposta

2

Se si dispone di una versione sufficientemente alta, è possibile provare una volta sola. Seguire le istruzioni qui: https://docs.angularjs.org/guide/expression#one-time-binding

Si è fondamentalmente a destra con il presupposto che angolare pensa che le date siano sempre nuove. Stai cambiando il valore con la valutazione nel controllo getter e angolare e gli orologi sporchi attivano un altro riassunto.

Puoi anche provare a analizzare la data in anticipo?

+0

Ho provato a nascondere le mie operazioni da angolari come questo, ma ottengo lo stesso risultato. public get TxDate(): Data { let dtoDate = moment (this.dto.TxDate) .toDate(); if (this._txDate === undefined || this._txDate === null) this._txDate = dtoDate; se (dtoDate.getFullYear()! = This._txDate.getFullYear() || dtoDate.getMonth()! = This._txDate.getMonth() || dtoDate.getDate()! = This._txDate.getDate()) { this._txDate = dtoDate; } return this._txDate; } – John

2

Ho trovato un modo tutto questo come segue:

distacco solo il dattiloscritto in quanto è più leggibile:

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; 

Questo sembra darmi quello che mi serve. La data di visualizzazione è associata a un'etichetta visibile in modo che sia possibile ottenere il formato di visualizzazione desiderato e il TxDate è associato a un controllo data-picker del modulo nascosto. In questo modo tutto sembra funzionare. E posso mantenere la mia data Dto nel formato ISO8601.