【问题标题】:Async input not updated Angular2异步输入未更新Angular2
【发布时间】:2017-05-01 09:20:25
【问题描述】:

我正在尝试在父组件中检索一些数据并在子组件中使用它。但未检测到更改(未触发 ngOnChanges)。

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

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

更新

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

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

 ...
</modal>

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;
      }
      );
  }
}

更新 2

如果我使用 zone.run() 它可以工作(但我仍然不知道为什么我必须这样做)

parent.component.ts

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

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  
 }
}

【问题讨论】:

  • 你能创建一个 plunker 来重现你的问题吗?
  • 检查Zone.current.name

标签: angular asynchronous


【解决方案1】:

尝试手动触发变更检测

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();
});

【讨论】:

  • 我在代码中遇到了什么问题,迫使我手动检测一些更改?我试图添加这一行“this.cdr.detectChanges();”前。 ngOnChanges 在子组件中被触发,但视图没有更新为正确的值
  • @isy 那你能把视图也包括进来吗?
  • @isy 你在哪里打电话给openModal()?在此之前,您的 selectedCountries 为空
  • 当用户单击编辑按钮以显示模式时,从父级调用 openModal 并使用“openChildModal”(我已经再次更新了我的代码)。
  • @isy 好的,您希望在视图中看到什么?
猜你喜欢
  • 2017-03-14
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多