Данные Angular Access из компонента в директиве

Итак, я пытаюсь создать директиву «автозаполнения» для проекта, который будет запрашивать API и отображать список результатов для выбора. У меня есть компонент, который отображает модальное окно с простым полем ввода. Мне нужно ввести текст в поле для поиска участников, щелкнуть элемент и добавить его в массив в компоненте.

Изменить: проблема, с которой я сталкиваюсь, заключается в том, что когда я вызываю this.wlAutocomplete.next(value);, он возвращается в мой компонент и выполняет вызов API с правильным значением из поля ввода, он не возвращает данные обратно. к директиве для обработки ответа от API там.

Пример StackBlitz: https://stackblitz.com/edit/angular-11erew < / а>

Компонент будет отслеживать массив выбранных элементов. Мне нужно уметь:

  • Вызовите мой API в компоненте, чтобы получить данные и вернуться к директиве
  • Директиве необходимо будет прочитать данные и отобразить список под полем ввода (здесь я могу сделать HTML).
  • Щелчок по элементу списка в раскрывающемся списке отправит этот выбор обратно компоненту для обработки по мере необходимости, например. добавить его в массив.

У моего компонента есть метод:

queryMembers(value: string): Subscription {
  return this.memberService.query({ term: value, groupKey: this.group.groupKey })
    .subscribe((members) => {
      console.log(members);
      return this.searchMemberList = members;
    });
}

Что я использую в шаблоне вот так:

<input (wlAutocomplete)="queryMembers($event)" class="uk-search-input" type="search" placeholder="Search...">

Вот код Директивы:

@Directive({
  selector: 'input[wlAutocomplete]'
})
export class AutocompleteDirective {
  modelChanged: Subject<string> = new Subject<string>();
  subscription: Subscription;
  debounce: number = 500;

  constructor() {
    this.subscription =
      this.modelChanged
        .pipe(debounceTime(this.debounce))
        .subscribe(value => {
          this.wlAutocomplete.next(value); // I need to get the data from component method passed into `wlAutocomplete`
        });
  }

  @Output() wlAutocomplete: EventEmitter<any> = new EventEmitter();

  @HostListener('input', ['$event'])
  onChange($event) {
    this.modelChanged.next($event.target.value);
  }
}

person Matt Brewerton    schedule 25.09.2018    source источник
comment
пожалуйста, отредактируйте свой вопрос, включите конкретный вопрос, любые ошибки и, если возможно, опубликуйте минимально полный пример, используя что-то вроде stackblitz.com   -  person FussinHussin    schedule 25.09.2018
comment
Моя проблема в том, что this.wlAutocomplete.next (value); успешно возвращается к методу компонента (queryMembers) со строкой и запрашивает API, но я не могу заставить компонент вернуть данные (элемент []) обратно в директиву для обработки там. У меня нет времени собрать рабочий пример, но при необходимости я могу посмотреть, как настроить его позже.   -  person Matt Brewerton    schedule 25.09.2018
comment
@FussinHussin Вот StackBlitz: stackblitz.com/edit/angular-11erew. Я изо всех сил пытаюсь понять, как вернуть данные из компонента в Директиву.   -  person Matt Brewerton    schedule 25.09.2018
comment
спасибо за пример, посмотрю. просто предупреждаю, что вы поместили личную информацию людей в пример   -  person FussinHussin    schedule 25.09.2018
comment
Итак, я немного запутался. Вы хотите, чтобы значение из вашей директивы было получено, где и для какой функции?   -  person FussinHussin    schedule 25.09.2018
comment
@FussinHussin Данные взяты из Json Placeholder API - это все случайно сгенерированные данные ^ - ^   -  person Matt Brewerton    schedule 25.09.2018


Ответы (1)


Хорошо, думаю, я понимаю, что вы сейчас пытаетесь сделать, спасибо за пример. Вы хотите отправить значения из родительского шаблона в директиву? в основном вам нужны входные данные для вашей директивы и привязка к ним в родительском элементе.

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

import {Directive, EventEmitter, HostListener, Input, Output} from '@angular/core';
import {Subject, Subscription} from "rxjs";
import {debounceTime} from "rxjs/operators";

@Directive({
  selector: 'input[wlAutocomplete]'
})
export class AutocompleteDirective {
  modelChanged: Subject<string> = new Subject<string>();
  subscription: Subscription;
  debounce: number = 500;

  // label and type your input, then handle it however you like
  @Input() value: any;

  constructor() {
    this.subscription =
      this.modelChanged
        .pipe(debounceTime(this.debounce))
        .subscribe(value => {
          console.log('value', value)
          console.log('directive', this.wlAutocomplete.next(value)); // I need to get the data from component method passed into `wlAutocomplete`
        });
  }

  @Output() wlAutocomplete: EventEmitter<any> = new EventEmitter();

  @HostListener('input', ['$event'])
  onChange($event) {
    console.log('directive called')
    this.modelChanged.next($event.target.value);
  }
}

шаблон

// bind to the input in the template
    AutoComplete: <input type="text" [value]="value" (wlAutocomplete)="queryMembers($event)" />

компонент

import { Component } from '@angular/core';
import {Subscription} from "rxjs";
import {MemberService} from './member.service'
import {Member} from './member';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  // send value to directive 
  value: any;
  name = 'Angular';
  group: any = { groupKey: 'test' };
  debugMemberList: Member[];
  constructor(private memberService: MemberService){}

  queryMembers(value: string): Subscription {
  return this.memberService.query({ term: value, groupKey: this.group.groupKey })
    .subscribe((members) => {
      console.log('In component: ', members);
      this.value = members;
      return this.debugMemberList = members;
    });
  }
}

Я не уверен, что это именно та реализация, которую вы ищете, но, надеюсь, она даст вам достаточно информации о передаче данных между родительским элементом и директивой, чтобы понять это.

person FussinHussin    schedule 25.09.2018
comment
Читая ответ, похоже, он должен дать мне то, что я хочу, я попробую позже сегодня, спасибо! - person Matt Brewerton; 25.09.2018