マテリアルダイアログへのデータの注入はうまく機能していますが、これらのデータが親/オープナーコンポーネントで変更された場合(たとえば(WAMP)サブスクリプションから)自動的に更新する方法はありますか?
[更新]
動作がどのようになるかを試すために、最小バージョンを作成しました: https://stackblitz.com/edit/angular-njh44v?embed=1&file=src/app/app.component.ts
右下のコンソールを開き、数字の付いた灰色のボックスをクリックします。ダイアログが現在の番号を取得し、それ以降は更新しないことがわかります。
[/ Update]
[更新2]
Jusmptyの2番目のアイデアに基づいて、これは一目で機能します(データが到着した後にダイアログが最初に表示/更新する場合でも): https://stackblitz.com/edit/ angle-thd34f?embed = 1&file = src/app/app.component.ts
[/ Update]
具体的なケースは次のようになります。
そして、この最後のアクション/ステップで、現在のデータが表示(注入)されますが、サブスクライブされたデータの何かが変更されても更新されないという問題が発生します。
@Component({
selector: 'app-area',
template: '<app-part *ngFor="let part of plan" [partData]="part"></app-part>'
})
export class AreaComponent {
plan = [];
planasync$ = this.wampService
.topic('sendplan')
.subscribe(
res => {
let tm = new TableMap();
this.plan = tm.tableToMap(res.argskw).filter((m) => m.area === 1);
},
err => console.log("res err", err),
() => console.log("res complete"));
constructor(private wampService: WampService) { }
}
import { PartDetailsDialogComponent } from './part-details-dialog/part-details-dialog.component';
@Component({
selector: 'app-part-details',
templateUrl: './part.component.html'
})
export class PartComponent {
@Input() partData: any;
constructor(public dialog: MatDialog) {}
openDetailsDialog(): void {
let dialogRef = this.dialog.open(PartDetailsDialogComponent, {
width: '650px',
height: '400px',
data: {
partData: this.partData
}
});
}
}
<mat-card (click)="openDetailsDialog()">
<mat-card-title>Nr: {{ partData.partNr }}</mat-card-title>
<mat-card-content>
<div>Current speed: {{ partData.speed }}</div>
</mat-card-content>
</mat-card>
@Component({
selector: 'app-part-details-dialog',
templateUrl: './part-details-dialog.component.html'
})
export class PartDetailsDialogComponent {
constructor(public dialogRef: MatDialogRef<PartDetailsDialogComponent>, @Inject(MAT_DIALOG_DATA) public data: any) { }
onNoClick(): void {
this.dialogRef.close();
}
}
<h1 mat-dialog-title>Part Details for Nr. {{ data.partData.partNr }}</h1>
<div mat-dialog-content>
<div>Current speed details: {{ data.partData.speed }}</div>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">Cancel</button>
<button mat-button [mat-dialog-close]="data.animal" cdkFocusInitial>Ok</button>
</div>
その代わりに、次のようにコンポーネントインスタンスのdata
を変更するだけです。
this.dialogRef.componentInstance.data = {numbers: value};
現時点では2つの方法がありますが、どちらもあまり好きではありませんが、ちょっと...
どちらの方法でも、データを通じてダイアログにオブザーバブルを送信する必要があります。
@Component({
selector: 'app-area',
template: '<app-part *ngFor="let part of planAsync$ | async; i as index" [partData]="part" [part$]="part$(index)"></app-part>'
})
export class AreaComponent {
plan = [];
constructor(private wampService: WampService) {
}
part$(index) {
return this.planAsync$
.map(plan => plan[index]);
}
get planAsync$() {
return this.wampService
.topic('sendplan')
.map(res => {
let tm = new TableMap();
return tm.tableToMap(res.argskw).filter((m) => m.area === 1);
});
}
}
@Component({
selector: 'app-part-details',
templateUrl: './part.component.html'
})
export class PartComponent {
@Input() partData: any;
@Input() part$
constructor(public dialog: MatDialog) {}
openDetailsDialog(): void {
let dialogRef = this.dialog.open(PartDetailsDialogComponent, {
width: '650px',
height: '400px',
data: {
partData: this.partData,
part$: this.part$
}
});
}
}
もちろん、問題は、とにかく直接データにアクセスできる場合、partDataを渡すことですら便利なことです。
@Component({
selector: 'app-part-details',
templateUrl: './part.component.html'
})
export class PartComponent, OnChanges {
@Input() partData: any;
private Subject part$ = new Subject();
constructor(public dialog: MatDialog) {}
ngOnChanges(changes){
this.part$.next(changes['partData']);
}
openDetailsDialog(): void {
let dialogRef = this.dialog.open(PartDetailsDialogComponent, {
width: '650px',
height: '400px',
data: {
partData: this.partData,
part$: this.part$
}
});
}
}
最後に、データにアクセスするには、htmlを次のように変更できます。
<div *ngIf="(data.part$ | async) as part">
<h1 mat-dialog-title>Part Details for Nr. {{ part.partNr }}</h1>
<div mat-dialog-content>
<div>Current speed details: {{ part.speed }}</div>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">Cancel</button>
<button mat-button [mat-dialog-close]="data.animal" cdkFocusInitial>Ok</button>
</div>
</div>
または、ダイアログコンポーネントでobservableをサブスクライブし、そこからデータを提供できます