1
votes

Renvoyer les données du modal au composant dans Angular

J'ai un autre problème avec Angular. Je ne sais pas comment renvoyer des données à partir d'un modal. Une liste d'objets s'affiche dans mon modal, puis après avoir cliqué sur un élément de la liste, je passe l'objet à la fonction. Comment recevoir cet objet dans un autre composant?

modal-geoname.component.html

export class MapViewComponent {

  private searchCountry: string;
  private searchText: string;

  public itemList: Geoname[] = [];

  constructor(private geonameService: GeonameService, private modalService: ModalService) {}

  searchCity() {
    this.geonameService.getCity(this.searchText, this.searchCountry).subscribe((geonames) => {
      this.modalService.showGeonameModal(geonames);
      this.searchText = '';
    });
  }

}

modal-geoname.component. ts

@Injectable({ providedIn: 'root' })
export class ModalService {

  bsModalRef: BsModalRef;

  constructor(private bsModalService: BsModalService) {}

  // ... other open modal functions ...

  showGeonameModal(geonames: Geoname[]) {
    this.bsModalRef = this.bsModalService.show(ModalGeonameComponent, {
      initialState: { geonames },
      class: 'modal-dialog modal-dialog-centered modal-lg',
      ignoreBackdropClick: true
    }).content.selectedItem.subscribe(selectedItem  => {
      console.log(selectedItem); 
      // I want to push selectedItem to itemList array in map-view.component.ts
    });
  }

}

modal.service.ts

export class ModalGeonameComponent implements OnInit {

  public geonames: Geoname[] = [];
  public selectedItem: Subject<boolean>;

  constructor(public bsModalRef: BsModalRef) {}

  selectGeoname(geoname: Geoname) {
    this.selectedItem.next(geoname);
  }

  ngOnInit() {
    this.selectedItem = new Subject();
  }

}

map-view.component.ts

<ng-scrollbar #scrollable track="vertical" *ngIf="geonames.length > 0">
  <table class="table table-hover mb-0">
    <tbody>
      <tr *ngFor="let geoname of geonames; let i = index" style="cursor: pointer;" (click)="selectGeoname(geoname)">
        <th scope="row">{{ i+1 }}</th>
        <td><span class="flag-icon flag-icon-{{ geoname.country | lowercase }} mr-2"></span>{{ geoname.country }}, {{ geoname.zipcode }} {{ geoname.place }}</td>
        <td>{{ geoname.admin }}</td>
      </tr>
    </tbody>
  </table>
</ng-scrollbar>

Je veux transmettre selectedItem à itemList. Veuillez vérifier l'exactitude de mon code car je ne veux pas apprendre une mauvaise programmation. Merci.


0 commentaires

3 Réponses :


1
votes

c'est possible dans BsModalService :

constructeur (modalService privé: BsModalService)

et vous pouvez ensuite utiliser ce qui suit:

const modal = this.modalService.show(ModalGeonameComponent);


(<ModalGeonameComponent>modal.content).onClose.subscribe(result => {
      if(result) {
        this.result = Object.assign({}, result);
        .....
      }
    });


2 commentaires

Je ne peux pas faire cela, car j'ai des modaux dans un service modal séparé.


@WojtekSzymczyk Ensuite, vous avez 2 options: 1. utiliser un autre modal sur le modal - ce qui est possible via BsModalService mais déconseillé et pas une bonne pratique UX. 2. changer la façon dont vous envisagez de concevoir la page. Ce que je recommande



1
votes

Vous pouvez y parvenir en utilisant Interaction avec les composants . Si les composants 'ModalGeonameComponent' sont un composant enfant de 'MapViewComponent', vous pouvez transmettre les données de l'enfant au parent en utilisant la propriété Output. Si ces deux composants sont au même niveau (pas parent - enfant), vous pouvez créer un service partagé entre eux (à l'aide d'observables) et transmettre les données d'un composant à un autre. Pour plus d'explications, vous pouvez consulter ce tutoriel < / p>


2 commentaires

Les modaux sont déjà en service séparé et je souhaite l'utiliser. Je ne sais pas comment utiliser Oberservables dans mon service.


Vous pouvez consulter la dernière étape du tutoriel ci-dessus, section Composants indépendants: partage de données avec un service .



0
votes

Merci pour vos réponses. Maintenant, je peux voir mon objet dans MapViewComponent sous la variable geoname. Mais j'ai un autre problème.

Le programme doit se comporter comme ceci: je choisis un élément de la liste dans le modal, puis passe l'objet à MapViewComponent où j'appelle la nouvelle fonction drawMap (object: Geoname) et ferme le modal . Comment faire? Comment fermer le modal et appeler la fonction?

Mon code actuel:

modal-geoname.component.html

export class MapViewComponent implements OnInit {

  private searchCountry: string;
  private searchText: string;

  private geoname: Geoname;

  constructor(private dataService: DataService, private geonameService: GeonameService, private modalService: ModalService) {}

  ngOnInit() {
    this.dataService.currentGeoname.subscribe(geoname => {
      this.geoname = geoname;
    });
  }

  searchCity() {
    this.geonameService.getCity(this.searchText, this.searchCountry).subscribe((geonames) => {
      this.modalService.showGeonameModal(geonames);
      this.searchText = '';
    });
  }

}

@Injectable({ providedIn: 'root' })
export class ModalService {

  bsModalRef: BsModalRef;

  constructor(private bsModalService: BsModalService) {}

  showGeonameModal(geonames: Geoname[]) {
    this.bsModalRef = this.bsModalService.show(ModalGeonameComponent, {
      initialState: { geonames },
      class: 'modal-dialog modal-dialog-centered modal-lg',
      ignoreBackdropClick: true
    });
  }

}

data.service.ts p>

export class DataService {

  private geonameSource = new BehaviorSubject<Geoname>('');
  currentGeoname = this.geonameSource.asObservable();

  selectGeoname(geoname: Geoname) {
    this.geonameSource.next(geoname);
  }

}

modal.service.ts

export class ModalGeonameComponent {

  private geonames: Geoname[] = [];

  constructor(private bsModalRef: BsModalRef, private dataService: DataService) {}

  selectItem(geoname: Geoname) {
    this.dataService.selectGeoname(geoname);
  }

}

map-view.component.ts

<ng-scrollbar #scrollable track="vertical" [ngStyle]="{'min-height': setScrollbarHeight() }" *ngIf="geonames.length > 0">
  <table class="table table-hover mb-0">
    <tbody>
      <tr *ngFor="let geoname of geonames; let i = index" style="cursor: pointer;" (click)="selectItem(geoname)">
        <th scope="row" style="width: 50px;">{{ i+1 }}</th>
        <td><span class="flag-icon flag-icon-{{ geoname.country | lowercase }} mr-2"></span>{{ geoname.country }}, {{ geoname.zipcode }} {{ geoname.place }}</td>
        <td>{{ geoname.admin }}</td>
      </tr>
    </tbody>
  </table>
</ng-scrollbar>


0 commentaires