Angular 异步输入未更新2
我试图在父组件中检索一些数据,并在子组件中使用它。但未检测到更改(未触发ngOnChanges) parent.component.tsAngular 异步输入未更新2,angular,asynchronous,Angular,Asynchronous,我试图在父组件中检索一些数据,并在子组件中使用它。但未检测到更改(未触发ngOnChanges) parent.component.ts @Component({ selector: 'parent', templateUrl: './parent.component.html' }) export class ParentComponent { countries: VisitedCountries; @ViewChild('childModalComponent') ch
@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;
});
}
}
@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
}
}
@Injectable()
export class UserService {
getUserProfil(userId: string) {
return this.http.get(url)
.toPromise()
.then(response => response.json() as User)
.catch(error => {
return error;
}
);
}
}
@Component({
selector: 'parent',
templateUrl: './parent.component.html'
})
export class ParentComponent {
function () {
this.zone.run(() => this.displayProfil());
}
}
@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
}
}
parent.component.html
<span (click)="openChildModal()">
<child-modal [countries]="countries"> </child-modal>
<modal>
...
// primeng autocomplete
<p-autoComplete [(ngModel)]="selectedCountries" [suggestions]="filteredCountriesMultiple" field="label" (completeMethod)="filterCountryMultiple($event)"
[multiple]="true">
</p-autoComplete>
...
</modal>
childModal.component.html
<span (click)="openChildModal()">
<child-modal [countries]="countries"> </child-modal>
<modal>
...
// primeng autocomplete
<p-autoComplete [(ngModel)]="selectedCountries" [suggestions]="filteredCountriesMultiple" field="label" (completeMethod)="filterCountryMultiple($event)"
[multiple]="true">
</p-autoComplete>
...
</modal>
更新2
如果我使用zone.run(),它会工作(但我仍然不知道为什么我必须这样做)
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;
});
}
}
@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
}
}
@Injectable()
export class UserService {
getUserProfil(userId: string) {
return this.http.get(url)
.toPromise()
.then(response => response.json() as User)
.catch(error => {
return error;
}
);
}
}
@Component({
selector: 'parent',
templateUrl: './parent.component.html'
})
export class ParentComponent {
function () {
this.zone.run(() => this.displayProfil());
}
}
@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
}
}
及
childModal.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;
});
}
}
@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
}
}
@Injectable()
export class UserService {
getUserProfil(userId: string) {
return this.http.get(url)
.toPromise()
.then(response => response.json() as User)
.catch(error => {
return error;
}
);
}
}
@Component({
selector: 'parent',
templateUrl: './parent.component.html'
})
export class ParentComponent {
function () {
this.zone.run(() => this.displayProfil());
}
}
@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
}
}
尝试手动触发更改检测
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在子组件中激发,但视图未使用正确的value@isy那么您也可以包含视图吗?@isy您在哪里调用
openModal()
?您的selectedCountries
是空的,直到当用户单击编辑按钮以显示模式(我再次更新了代码)时,从父级调用该点OpenModel(openChildModal)为止。@y确定您希望在视图中看到什么?您能创建一个复制您的问题的plunker吗?检查Zone.current.name