Angular показать результаты поиска в разных компонентах - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть функция поиска на домашней странице (homePageComponent), и когда я нажимаю на поиск, она перенаправляет на другую страницу, называемую страницей списка поиска (searchListComponent), и у меня появляется еще один компонент в самом searchListComponent (в соответствии с дизайном приложения), который называется компонент карты поиска (searchCardComponent), где я показываю все результаты поиска. я пытался отправить поисковый текст из homePageComponent в searchCardComponent с помощью eventemitter, но почему-то данные не передаются. было бы хорошо, если бы кто-нибудь помог с этим.

Пример кода ниже

homePageComponent

HTML (Продукт A )

     <ng-select
              class="col-md-5 solution-list-dropdown"
              [items]="productType$ | async"
              [addTag]="true"
              [(ngModel)]="selectedSolutionId"
              bindLabel="description"
              bindValue="id"
              placeholder="Select"
              [clearable]=true
              [searchable]=true
              [dropdownPosition]="'down'"
              [ngClass]="{ 'dropdown-is-invalid': submitted && f.category.errors }">
           </ng-select>
<button class="red-button"  (click)="searchRedirection(selectedSolutionId)">
          Search
        </button>

машинопись

  @Output() searchValue = new EventEmitter<string>();

   public searchRedirection(selectedSolutionId: string) {
      this.searchValue.emit(selectedSolutionId);
      this.router.navigate(['/category/' + selectedSolutionId]);
    }

SearchListComponent

HTML

<div class="container-fluid product-card-container p-0" id="hor-divider">

    <div class="product-list">
      <app-product-card (searchValue)="onApplyEvent($event)" *ngFor="let product of products | filter:searchText | filter:filterText" [product]="product">
      </app-product-card>
    </div>

</div>

Typescript

  onApplyEvent(event: any): any {
    console.log('event : ' + event);
  }

Здесь я ожидаю, что в журнале консоли будет напечатано «событие: Продукт A», так что я смогу использовать его для привязки этого значения к * ngFor. Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Генератор событий, как вы заявили, не будет работать таким образом, потому что он может быть прочитан только родительским компонентом homePageComponent с этим декоратором @Output. Вы можете создать отдельный класс событий и импортировать его в оба компонента (тот, который излучает, и тот, который получает), но, на мой взгляд, это ужасная практика. Лучше всего либо отправить поисковое слово в качестве параметра запроса на маршруте, либо создать общую службу, которая будет иметь объект BehaviorSubject в качестве поля, поскольку он может хранить и повторно передавать последнее переданное значение. Вот пример параметров

this.router.navigate(['/category'], { queryParams: { selectedSolutionId: selectedSolutionId } });

, чтобы получить значение в SearchListComponent, вы должны сделать

import { ActivatedRoute } from '@angular/router';
.....
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.route.queryParams
  .subscribe(params => {
    this.selectedSolutionId = params.selectedSolutionId;
    //then you could pass this.selectedSolutionId as @Input to app-product-card component
    console.log(this.selectedSolutionId );
  });
}
0 голосов
/ 08 апреля 2020

вы можете использовать что-то вроде общего сервиса для передачи данных между двумя компонентами,

В этом сервисе мы могли бы использовать subject или eventEmitter (но тема лучше), а в компоненте домашней страницы мы можем выбросить эту тему

, находясь в компоненте карты поиска, мы подпишемся на эту тему для получения данных

. Вот пример

shared.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({providedIn: 'root'}) // the service is available application wide, so the same instance of this class will be available in the whole application

export class SharedService {

  searchSubject = new Subject<String>(); // a new subject of type String, replace it with your data type
}

и в домашнем компоненте, после выбора решения, просто отправьте его в общую службу, вы можете добавить (изменить) или (ngModelChange) в свой список в html, чтобы проверить изменения и один раз произошло изменение, выделите тему

, чтобы функция в домашнем компоненте html могла быть чем-то вроде

(ngModelChange) = "onSelectSolution()"

и в файле ts

constructor(private sharedService: SharedService) { // inject the shared service

}

onSelectSolution() {
  // just emit the event
  this.sharedService.searchSubject.next(this.selectedSolutionId); // emit the value to the shared service
}

затем в компоненте карты поиска

import { OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';

// add the selector 

export class SearchCardComponent implements OnInit, OnDestroy {
  subscription: Subscription // define some subscription property to assign the subscription to, and destroy it once we left this component

  constructor(private sharedService: SharedService){}

  ngOnInit() {
    // here to subscribe to the subject in the sharedService
    this.subscription = this.sharedService.searchSubject.subscribe((mySearch: String) => {
      // now we passed the search from the home component to the search card component
    });
  }

  ngOnDestroy() {
    // just unsubscribe the subscription we used
    this.subscription.unsubscribe();
  }
}

проверьте эту ссылку, чтобы увидеть разницу между (change) и (ngModelChange) разницей между (изменить) и (ngModelChange)

...