Why does angularjs digest go into an infinite loop with a date retrieval function

I have a DTO object that has a Date parameter. I wrap this Dto in a view model object, whose properties I then bind in my view to the label.

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

In the view model, I have a getter. (I am using TypeScript)

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

emitted javascript:

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

I believe that the reason I create a new date in getter and angular believes that this means the dates are always new, and it continues to get the date until the model stabilizes, which will cause an infinite loop.

Why does angular do this?
Why does he keep calling the getter again and again, what's wrong, just calling him once?
Can I tell angular to just call the receiver once and accept the value that it is given?

+5
source share
2 answers

If you are on a high enough version, you can try a one-time binding. Follow the instructions here: https://docs.angularjs.org/guide/expression#one-time-binding

Basically, you're right with the assumption that angular thinks dates are always new. You change the value with the score in your getter and the angular dirty check, and the clock starts another digest.

Could you also analyze the date ahead of time?

+2
source

I found a way around this as follows:

posting only typescript as it is more readable:

  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; 

This seems to give me what I need. The display date is bound to a visible label so that I can get the display format that I want, and TxDate is bound to a hidden date picker control. This way it all works. And I can save the Dto date in ISO8601 format.

+2
source

Source: https://habr.com/ru/post/1239076/


All Articles