javascript - Angular'da bir bileşenden diğerine veri aktarma


Bir arama işlevi içeren bir uygulama üzerinde çalışıyorum.

Şu anda uygulamada 2 bileşenim var 1. Navbar 2. SearchGridList

Navbar bileşeni bir metin kutusu içerir, bu kutuya bir arama sorgusu yazarsınız ve enter tuşuna basarsınız, bu bileşen bir API çağrısı yapar ve veriyi alır. Veri geri geldiğinde, bu veriyi SearchGridList bileşeninde bir diziye doldurmak istiyorum.

Angular'da bileşenler arasında veri iletmeyi anlamakta zorlanıyorum, birisi lütfen koduma bakabilir ve bana rehberlik edebilir mi?

navbar.component.ts

import { Component, OnInit, Input, Output } from '@angular/core';
import {DataService} from '../../services/data.service';
import {SearchResults} from '../class/search.class';
import {SearchGridListComponent} from '../search-grid-list/search-grid-list.component';
import { EventEmitter } from '@angular/core';

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

  searchQuery : String;
  //searchResultList : Array<any> = [];

  constructor(private dataService :  DataService) { }

  doSearch () : any
  {
    this.dataService.doSQLSearch(this.searchQuery)
    .then ((data:any)=>{
      for (var i =0; i<data.Results.length;i++){
        let searchObj = new SearchResults(data.Results[i]);
        //I want to push data into array from SearchGrid like this 
        resultGridList.push(searchObj);

      }
    });
   }

  ngOnInit() {
  }
}

navbar.component.html

<mat-toolbar class="main-header">
  <a href="/">
  <img src="../../../assets/vms-header-logo.png" id= "header-logo">
  </a>
    <form class="search-box">
      <mat-form-field  class="search-box-full-width">
        <input id ="search-textbox" matInput placeholder="Enter a Barcode, DSID or any search term" name="Search" [(ngModel)]="searchQuery" (keyup.enter)="doSearch()" autocomplete="off">
      </mat-form-field>
    </form>
</mat-toolbar>

search-grid.component.ts

import { Component, OnInit, Input } from '@angular/core';
import {NavbarComponent} from '../navbar/navbar.component';

@Component({
  selector: 'app-search-grid-list',
  templateUrl: './search-grid-list.component.html',
  styleUrls: ['./search-grid-list.component.css'],
})
export class SearchGridListComponent implements OnInit {
  resultGridList : Array <any> = [];
  constructor() { }

  ngOnInit() {
  }

}

Cevap #1

Kendi DataService içinde bir BehaviorSubject oluşturabilirsiniz

private messageSource = new BehaviorSubject<string>('service');

Veri aktarmak için bu demo'ya başvurabilirsiniz.

https://stackblitz.com/edit/behavior-subject-2019

Cevap #2

Navbar'a aşağıdaki @Output olayını eklemeniz gerekiyor:

export class NavbarComponent implements OnInit {
   ...
   @Output() public found = new EventEmitter<any>();
   ...
   doSearch () : any
   {
    this.dataService.doSQLSearch(this.searchQuery) .then ((data:any)=>{
      for (var i =0; i<data.Results.length;i++){
        let searchObj = new SearchResults(data.Results[i]);

        this.found.emit(searchObj);  // !!!! here emit event
                                     // however emitting events in loop looks strange... better is to emit one evet

      }
    });
   }
   ...
}

Tamam, grid bileşeninizde @Input öğesini resultGridList parametresi olarak kullanın

export class SearchGridListComponent implements OnInit {

  @Input() public resultGridList : Array <any> = [];
  ...
}

Tamam ve şimdi App bileşeninizde bu ikisini şu şekilde birleştirin

Uygulama şablonu html:

<app-navbar (found)="handleResults($event)"></app-navbar>

<app-search-grid-list [resultGridList]="data"></app-search-grid-list>

Ve App ts dosyasında:

data = [];
...

handleResults(searchObj) {
  this.data = searchObj
}

İlgili makaleler