简体   繁体   English

异步输入未更新Angular2

[英]Async input not updated Angular2

I'm trying to retrieve some data in a parent component and use it in a child component. 我正在尝试在父组件中检索一些数据,并在子组件中使用它们。 But changes are not detected (ngOnChanges is not fired). 但是未检测到更改(未触发ngOnChanges)。

parent.component.ts parent.component.ts

@Component({
  selector: 'parent',
  templateUrl: './parent.component.html'
})
export class ParentComponent {
  countries: VisitedCountries;
  @ViewChild('childModalComponent')
  childModalComponent: ChildModalComponent;


  openChildModal() {
    this.childModalComponent.openModal();
  }

  displayProfil() {
    var that = this;

   // If I put this here, child component has an updated variable => ngOnChanges is fired
   // this.countries = new VisitedCountries(...)

    this.userService.getUserProfil()
      .then(result => {
            // this.countries is not updated in child component
            that.countries = new VisitedCountries(result) as VisitedCountries;

      });
  }
}

parent.component.html parent.component.html

<span (click)="openChildModal()">
<child-modal [countries]="countries"> </child-modal>

UPDATED 更新

childModal.component.ts childModal.component.ts

@Component({
  selector: 'child-modal',
  templateUrl: './childModal.component.html'
})
export class ChildModalComponent implements OnInit, OnChanges {
  @Input()
  countries: VisitedCountries;
  selectedCountries: Country[];

  ngOnChanges(changes: SimpleChanges) {
   // not fired with async content
  }

  openModal() {
    this.selectedCountries = [];

    // simplified algo
    for (country in this.countries) {
      this.selectedCountries.push(country); 
    }

    // this.selectedCountries is well filled at this point
  }

}

childModal.component.html childModal.component.html

<modal>
  ...
    // primeng autocomplete
    <p-autoComplete [(ngModel)]="selectedCountries" [suggestions]="filteredCountriesMultiple" field="label" (completeMethod)="filterCountryMultiple($event)"
        [multiple]="true">
    </p-autoComplete>

 ...
</modal>

user.service.ts user.service.ts

@Injectable()
export class UserService {
  getUserProfil(userId: string) {
    return this.http.get(url)
      .toPromise()
      .then(response => response.json() as User)
      .catch(error => {
        return error;
      }
      );
  }
}

UPDATE 2 更新2

If I use zone.run() it works (but I still don't know why I have to do this) 如果我使用zone.run()可以正常工作(但我仍然不知道为什么必须这样做)

parent.component.ts parent.component.ts

@Component({
  selector: 'parent',
  templateUrl: './parent.component.html'
})
export class ParentComponent {
  function () {
    this.zone.run(() => this.displayProfil());
  }
}

and

childModal.component.ts childModal.component.ts

@Component({
  selector: 'child-modal',
  templateUrl: './childModal.component.html'
})
export class ChildModalComponent implements OnInit, OnChanges {
  @Input()
  countries: VisitedCountries;
  selectedCountries: Country[];

  openModal() {
    this.selectedCountries = [];
    this.zone.run(() => {
      // I had another async call here
      service.getObject().then (() => {
        for (country in this.countries) {
          this.selectedCountries.push(country); 
        }
      });
    }); 

   // or this.ref.detectChanges(); also works  
 }
}

Try triggering change detection manually 尝试手动触发变更检测

import {ChangeDetectorRef} from '@angular/core'

export class ParentComponent {

  constructor(private cdr: ChangeDetectorRef){}

  ...

this.userService.getUserProfil()
  .then(result => {
        // this.countries is not updated in child component
        that.countries = new VisitedCountries(result) as VisitedCountries;
        this.cdr.detectChanges();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM