简体   繁体   English

如何将 BehaviorSubject 传递给 MatDialog 数据?

[英]How can i pass BehaviorSubject to MatDialog data?

I have this piece of code, and i need data to change dynamically.我有这段代码,我需要动态更改数据。 So i decided to use stream for that.所以我决定为此使用流。 The problem is that it seems to copy stream, and it doesn't work... Is there any way to pass it there?问题是好像是copy流,而且不行……有什么办法可以传到那里吗? Or if it is possible, maybe there is some other solution?或者如果可能的话,也许还有其他解决方案? Any feedback would be appreciated.对于任何反馈,我们都表示感谢。

warehouse-stack-component.ts仓库堆栈组件.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();
  }
}

stack-pallets-component.ts stack-pallets-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
      }
    })
  }
}

stack-pallets-component.html stack-pallets-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>

Streams should be accessed from a shared service , and not a component.应该从共享服务而不是组件访问流。 The reason is generally cause you will run into a cyclical import.原因通常是因为您会遇到周期性导入。 Instead of injecting the stream into the next component, just subscribe to the stream that lives within the service from that component.无需将流注入下一个组件,只需从该组件订阅位于服务中的流。 You can use pallets$.next(pallets) from any component that has the service injected in its constructor.您可以从任何在其构造函数中注入服务的组件中使用pallets$.next(pallets) Then just inject that service into whatever component you'd like, and subscribe to it.然后只需将该服务注入您想要的任何组件,然后订阅它。

For memory management, it's important to unsubscribe to your subscriptions.对于内存管理,取消订阅您的订阅非常重要。 I like to use a helper for this (UntilDestroy);我喜欢为此使用助手 (UntilDestroy); where it will keep subscriptions until destruction of the component.它将保持订阅直到组件销毁。

Here's one way to do it.这是一种方法。

warehouse-stack.component.ts仓库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仓库.service.ts

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

stack-pallets.component.ts stack-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() {}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM