Как ввести наблюдаемое в веб-компонент Angular

Обратите внимание, что этот вопрос НЕ касается обычных компонентов Angular. Я специально спрашиваю о многоразовом настраиваемом элементе, созданном с помощью Angular, также называемом веб-компонентом Angular.

У меня есть многоразовый веб-компонент Angular 10, размещенный внутри другого веб-приложения Angular 10. Используя имена атрибутов в нижнем регистре, разделенные тире (например, my-data), я могу ввести строку в веб-компонент Angular, который имеет @Input с нижним регистром верблюда (например, myData).

HOST APP имеет следующую разметку:

<my-custom-element my-data="test"></my-custom-element>

Многоразовый веб-компонент - my-custom-element:

@Input() myData: string;

Строка работает нормально и передается в веб-компонент. Теперь, как передать наблюдаемое веб-компоненту? Пример (это не работает, поскольку он принимает то, что находится внутри, как буквальную строку.)

РАЗМЕТКА ПРИЛОЖЕНИЯ ПРИЛОЖЕНИЯ:

<my-custom-element 
    my-data="test"
    fetch-event="eventsSubject.asObservable()"
></my-custom-element>

КОМПОНЕНТ ХОЗЯЙСТВЕННОГО ПРИЛОЖЕНИЯ:

eventsSubject: Subject<void> = new Subject<void>();

 handleButtonClick(event: any): void {
   this.eventsSubject.next();
}

Многоразовый веб-компонент - my-custom-element:

@Input() myData: string;
@Input() fetchEvent: Observable<void>;

Я также пробовал следующее, что тоже не работает: [fetch-event] = eventsSubject.asObservable ()

Если использование @Input для передачи наблюдаемых веб-компонентов Angular не подходит, дайте мне знать. Я также попробовал this.elRef.nativeElement.attributes['fetchEvent'].value, который у меня тоже не сработал.


person snowleopard    schedule 07.09.2020    source источник
comment
пожалуйста, опубликуйте свой html-код, включая теги сценария   -  person Rafi Henig    schedule 08.09.2020
comment
Вы пробовали что-то вроде: eventsSubject.asObservable () | асинхронный?   -  person millenion    schedule 08.09.2020


Ответы (2)


Ваш компонент:

private eventsSubject: Subject<void> = new Subject<void>();
public subject = eventsSubject.asObservable();    

handleButtonClick(event: any): void {
 this.eventsSubject.next();
}

HTML:

<my-custom-element [myData]="subject"></my-custom-element>

Реализация нестандартного элемента:

@Component({
  selector: 'my-custom-element'
})
export class MyCustomElement {
  @Input()
  public myData: Observable<any>;

}
person Bargros    schedule 08.09.2020
comment
скобки [] не работают с веб-компонентом. Имя входных данных должно быть в кебаб-регистре в приложении для хостинга и будет передаваться только в виде строк. Как выяснилось, после долгих исследований я обнаружил, что нельзя передавать какой-либо сложный ввод в веб-компоненты Angular. - person snowleopard; 09.09.2020
comment
Да, вы правы, но я не понимаю, почему вы пытаетесь это сделать в первую очередь, когда вы можете использовать асинхронный канал в шаблоне для передачи значения дочернему компоненту и тому, что вы делаете с данными, которые вы может излучать из дочернего компонента обратно в родительский - person Bargros; 10.09.2020

После большого количества исследований и выяснения того, что нельзя передавать сложные данные в веб-компонент Angular через @Input, я поступил именно так, и до сих пор у меня это хорошо работало.

Поскольку @Outputs веб-компонента Angular do позволяет передавать больше, чем просто строки out, вместо этого я создал наблюдаемый объект внутри веб-компонента, немедленно подписываюсь на прослушивание событий, и сразу же передал это хост-приложению Angular. Затем в главном приложении этот наблюдаемый объект принимается через разметку и используется для трансляции события в прослушивающий веб-компонент.

Веб-компонент (my-custom-element - это селектор, устанавливаемый как имя экспортируемого компонента внутри ngDoBootstrap () моего app.module.ts):

@Output() setUpObservable = new EventEmitter<Subject<void>>();
eventsSubject: Subject<void> = new Subject<void>();
fetchEvent: Observable<any>;

ngOnInit(): void {
   eventsSubject: Subject<void> = new Subject<void>();
     fetchEvent: Observable<any>;

   this.fetchEvent = this.eventsSubject.asObservable();
       this.eventSubscription = this.fetchEvent.subscribe((x) => {
         // some code in here that I did not want to run until it was initiated by the host app
       });
       this.setUpObservable.emit(this.eventsSubject); // immediately send out the observable
}

Разметка хост-приложения:

<my-custom-element 
    (setUpObservable)="handleSetUpObservable($event)"
></my-custom-element>

Компонент основного приложения:

eventsSubject: Subject<void> = new Subject<void>();

onButtonClick(): void {
 this.eventsSubject.next(someData); // this talks to the Web component to tell it to do stuff
}

handleSetUpObservable(event: CustomEvent): void {
    this.eventsSubject = event.detail.observers[0];
}
person snowleopard    schedule 09.09.2020