2

I have the following problem-

component A:

<!-- LIST OF URLs-->
<exl-file-list  
  *ngIf="hasLinks()"
  listTitle="Added links:"
  [expandable]="editableFiles"
  expandAllButton="Edit metadata"
  (edit)="onLinkEdit($event)"
  (expandAll)="allLinksEditable = !allLinksEditable"
  (removeAll)="onRemoveAllLinks()">

  <!-- URL items -->
  <exl-file-list-item
    *ngFor="let link of depositFormDataService.mainForm.value.links let index = index"
    [item]="link"
    [index]="index"
    (remove)="onLinkRemove($event)"
    (edit)="onLinkEdit($event, index)">

    <!-- metadata of each URL -->
    **<esp-deposit-link-metadata
    [index]="index">
    </esp-deposit-link-metadata>**

  </exl-file-list-item>
</exl-file-list>

component B- esp-deposit-link-metadata:

<div class="metadata-container">
  <mat-form-field class="hasnt-underline">
    <mat-label>Description</mat-label>
    <textarea 
      matInput 
      [(ngModel)]="description" 
      **(ngModelChange)="onChangeDescription()" 
      ** #textarea placeholder="Describe the link" 
      matTextareaAutosize></textarea>
  </mat-form-field>
</div>

onChangeDescription method, updated my formGroup in depositFormDataService.mainForm.links

onChangeDescription(){
  this.depositFormDataService
    .updateLinkDescription(this.index,this.description);
}

it's content:

updateLinkDescription(index, description){
  const link = this.links.at(index) as FormGroup;
  link.setControl('description', new FormControl(description));
}

depositFormDataService.mainForm holds the links as FormArray. link is an object with three formControls that one of them is 'description'.

Each time that onChangeDescription() is called the constructors of exl-file-list-item and esp-deposit-link-metadata are called and all the view is refreshed, and I have no reason why.

danda
  • 553
  • 10
  • 30
  • Thanks! regarding "[(ngModel)]="description" (ngModelChange)="onChangeDescription()" " comment you gave me before- if I write [ngModel], the description field doesn't update at all.. – danda Oct 17 '18 at 11:04

1 Answers1

1

Whenever you make any changes in depositFormDataService.mainForm.value.links, Angular detect changes and it renders the content again.

Since you have used the both of those component inside *ngFor="let link of depositFormDataService.mainForm.value.links, it will re-initialized the component.

in ts

trackByLink = (index: number, link : any) => link.url; //check if you have `url` if not then you other unique property.

in html

`*ngFor="let link of depositFormDataService.mainForm.value.links ; trackBy:trackByLink `
Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
  • Although I saw this- https://stackoverflow.com/questions/42244690/does-ngfor-directive-re-render-whole-array-on-every-mutation?fbclid=IwAR0a3Z1RwdnEC843XL-5ECqFnEEYD6_zK1vM7dhFl50V2xsza-zoyF3mTj8 According to it, it should not render the content again. – danda Oct 17 '18 at 05:05
  • 1
    Its difficult to tell the exact issue without looking at your entire code however you can fix it by using `trackBy`. Updated my answer. – Sunil Singh Oct 17 '18 at 05:11
  • By adding the "track by" the component will not be re-initialized? – danda Oct 17 '18 at 05:19
  • 1
    Yes, it will not. This way we are telling the if the link is same as before and no re-iteration is required. – Sunil Singh Oct 17 '18 at 05:24