Angular Material对话框:如何在父组件中更改注入的数据时更新它们?

前端之家收集整理的这篇文章主要介绍了Angular Material对话框:如何在父组件中更改注入的数据时更新它们?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
将数据注入到材质对话框中效果很好,但是如果它们在父/开启组件中发生变化(例如来自(WAMP)订阅),如何自动更新这些数据?

[更新]
我创建了一个最小版本来试验行为是如何:https://stackblitz.com/edit/angular-njh44v?embed=1&file=src/app/app.component.ts
打开右下方的控制台,然后单击带有数字的灰色框.您会看到对话框获取当前数字,之后不再更新.
[/更新]

[更新2]
基于Jusmpty的第二个想法,这个接缝一见钟面(即使对话框在数据到达后第一次显示/更新):
https://stackblitz.com/edit/angular-thd34f?embed=1&file=src/app/app.component.ts
[/更新]

具体案例如下:

>有一个区域组件订阅WAMP服务并获取包含部分的所有数据.这将使用* ngFor绘制所有部件.
文件area.component.ts
>每个部分都有一个显示一些数据的组件.如果订阅中的数据发生更改,则视图会针对每个/所有部件正确并自动更新.
文件part.component.ts和part.component.html
>在每个部分上,单击将打开一个对话框,其中显示更多数据.
文件part-details-dialog.component.ts和part-details-dialog.component.html

在最后一个操作/步骤发生当前数据显示(注入)的问题,但如果订阅数据中的某些内容发生更改,则不再更新.

area.component.ts

@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) { }
}

part.component.ts

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

part.component.html

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

部分细节,dialog.component.ts

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

部分细节,dialog.component.html

<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>
我现在有两种方法可以想到,我也不喜欢,但是嘿……

两种方式都涉及通过数据向对话框发送observable.

>您可以将零件的observable传递给零件组件,然后将数据中的observable传递给对话框.然后,该对话框可以订阅observable并以这种方式获取更新.

AreaComponent

@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,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,part$: this.part$
      }
    });
  }
}

最后,要访问数据,您可以将html更改为

对话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,并从那里提供数据

原文链接:https://www.f2er.com/angularjs/142056.html

猜你在找的Angularjs相关文章