2

In an Angular 2 application I am writing, I have a select element that is bound to a field in the controller via [(ngModel)]:

<select [(ngModel)]="dateInfo.year" class="form-control">
  <option *ngFor="let year of getYearList()" [value]="year">{{year}}</option> 
</select>

dateInfo is a property in the controller that refers to a DateInfo object contained in a service called DateService:

@Injectable()
export class DateService {
  public dateInfo: DateInfo = {
    year: 2016
  }
}

The DateInfo object itself is a simple Typescript interface that just stores the year:

export interface DateInfo {
  year: number
}

The reason I am using this interface is to propagate changes to year to all components that use DateService, as per the first answer to this question.

For some reason, when the model is changed from the select element, the whole application freezes (tested in Chrome and Edge). I have made a plunker to illustrate the problem here.

Thanks in advance!

Community
  • 1
  • 1
Erik Jenkins
  • 21
  • 1
  • 4

1 Answers1

1

The problem is caused by getYearList() returning a new array instance for every call. Every time Angulars change detection runs it detects a change because it gets a new array every time. I wonder why you didn't get a "expression has changed since it was last checked thought"

Caching the result fixes the issue http://plnkr.co/edit/UKA35jIa9v6jFfrbJJuz?p=preview

This why it's usually bad practice to call methods from the template. Rather assign the result of a method call to a property and bind to this property instead.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Sorry if I didn't explain well, but my goal is to generate a new year list every time `year` is changed so that `year` is in the middle of the list. The `getYearList()` method must return a new array every time `year` is changed. – Erik Jenkins Aug 04 '16 at 15:12
  • I see, didn't investigate close properly. http://plnkr.co/edit/UKA35jIa9v6jFfrbJJuz?p=preview – Günter Zöchbauer Aug 04 '16 at 15:36