如何将 BehaviorSubject 传递给 MatDialog 数据?

How can i pass BehaviorSubject to MatDialog data?

我有这段代码,我需要数据动态变化。所以我决定为此使用流。问题是好像是copy stream,不行啊。。。有什么方法可以传过去吗?或者如果可能的话,也许还有其他解决方案?如有任何反馈,我们将不胜感激。

仓库堆栈-component.ts

import { CdkDragEnd, CdkDragStart } from '@angular/cdk/drag-drop';
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { MatDialog, MatDialogRef } from '@angular/material/dialog';
import { StackPalletsComponent } from '../modals/stack-pallets/stack-pallets.component';
import { MainServiceService } from '../services/main-service.service';
import { Observable, interval, BehaviorSubject, Subject } from 'rxjs';
import { Pallet } from '../models/pallet';

@Component({
  selector: 'app-warehouse-stack',
  templateUrl: './warehouse-stack.component.html',
  styleUrls: ['./warehouse-stack.component.css']
})
export class WarehouseStackComponent implements OnInit{

  @Input() warehouseStackID = null;
  @Input() name = null;
  @Input() position = null;
  @Input() set pallets(pallets:Pallet[]) {
    this.pallets$.next(pallets);
  }

  public pallets$:BehaviorSubject<Pallet[]> = new BehaviorSubject<Pallet[]>([]);
  
  public dialogRef: MatDialogRef<StackPalletsComponent>;


  constructor(public mainService:MainServiceService,public dialog:MatDialog) { }


  public dragging:boolean;


  
  ngOnInit(): void {

  }

  updatePosition(e: CdkDragEnd) {
    this.mainService.updateStackPosition(this.warehouseStackID, e.source.getFreeDragPosition().x, e.source.getFreeDragPosition().y)
  }

  public handleDragStart(event: CdkDragStart): void {
    this.dragging = true;
  }

  openDialog() {
    this.dialogRef = this.dialog.open(StackPalletsComponent, {
      data: {
        warehouseStackID: this.warehouseStackID,
        pallets$: this.pallets$
      } 
    });
  }

  handleClick(event: MouseEvent): void {
    if (this.dragging) {
      this.dragging = false;
      return
    } 
    this.openDialog();
  }
}

堆叠托盘-component.ts

import { Component, Inject, OnInit } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Pallet } from 'src/app/models/pallet';
import { MainServiceService } from 'src/app/services/main-service.service';
import { CreatePalletComponent } from '../create-pallet/create-pallet.component';

@Component({
  selector: 'app-stack-pallets',
  templateUrl: './stack-pallets.component.html',
  styleUrls: ['./stack-pallets.component.css']
})
export class StackPalletsComponent implements OnInit {

  constructor(public mainService:MainServiceService, public dialogRef:MatDialogRef<StackPalletsComponent>, public dialog:MatDialog,@Inject(MAT_DIALOG_DATA) public data: {warehouseStackID: number, pallets$:any}) { }

  ngOnInit(): void {
  }

  showCreationModal() {
    this.dialog.open(CreatePalletComponent, {
      data: {
        isStackPallet: true,
        warehouseStackID: this.data.warehouseStackID
      }
    })
  }
}

堆叠托盘-component.html

<div class="pallets">
    <app-pallet *ngFor="let pallet of this.data.pallets$|async" [position]="{x:pallet.positionX, y:pallet.positionY}" [pallet]="pallet"></app-pallet>
    <div class="cubeRow">
        <div class="cube"></div>
        <div class="cube"></div>
    </div>
    <div class="cubeRow">
        <div class="cube"></div>
        <div class="cube"></div>
    </div>
    <div class="cubeRow">
        <div class="cube"></div>
        <div class="cube"></div>
    </div>
    <div class="buttons">
        <button class="btn-floating btn-large waves-effect waves-light red" style="margin-top: 5px;" (click)="showCreationModal()"><i class="material-icons">add</i></button>
    </div>
</div>

应从 共享服务 而不是组件访问流。原因一般是你会运行进入循环导入。无需将流注入下一个组件,只需订阅来自该组件的服务中的流即可。您可以从任何在其构造函数中注入服务的组件使用 pallets$.next(pallets)。然后将该服务注入您想要的任何组件,并订阅它。

对于内存管理,取消订阅很重要。我喜欢为此使用一个助手(UntilDestroy);它将在组件销毁之前保留订阅。

这是一种方法。

仓库-stack.component.ts

@UntilDestroy({ checkProperties: true })
@Component({
  selector: 'app-warehouse-stack',
  templateUrl: './warehouse-stack.component.html',
  styleUrls: ['./warehouse-stack.component.css']
})
export class WarehouseStackComponent implements OnInit, OnDestroy, OnChanges {
 @Input() set pallets(pallets:Pallet[]) {}
constructor(warehouseService: WarehouseService) {}

  ngOnChanges(changes: SimpleChanges) {
    if (changes.pallets) {
      this.warehouseService.pallets$.next(changes.pallets.currentValue)
    }
  }

 openDialog() {
    this.dialogRef = this.dialog.open(StackPalletsComponent, {
      data: {
        warehouseStackID: this.warehouseStackID
      } 
    });
  }
}

ngOnDestroy() {}

warehouse.service.ts

@Injectable({ providedIn: 'root' })
export class WarehouseService {
  pallets$: BehaviorSubject<Pallet[]> = new BehaviorSubject<Pallet[]>([])
}

堆栈-pallets.component.ts

@UntilDestroy({ checkProperties: true })
@Component({
  selector: 'app-stack-pallets',
  templateUrl: './stack-pallets.component.html',
  styleUrls: ['./stack-pallets.component.css']
})
export class StackPalletsComponent implements OnInit, OnDestroy {
 pallets: Pallet[] | []
 palletsSub$: Subscription | undefined
constructor(warehouseService: WarehouseService) { 
 this.palletsSub$ = warehouseSevice.pallets$.subscribe((pallets) => {
     this.pallets = pallets
   })
 }
}

ngOnDestroy() {}