Настройка прослушивателя событий для экспортированного веб-компонента Angular Elements

РЕДАКТИРОВАТЬ: это веб-компонент, экспортированный из Angular с использованием Angular Elements, и не является традиционным Angular

Я экспериментирую с Angular Elements и создал компонент NgFor, который загружает файл JSON ниже.

[ 
{  
    "id":1,
    "name": "star 1",
    "image":"https://picsum.photos/id/1059/400/400",
    "text":"Text about star 1"
},
{  
    "id":2,
    "name": "star 2",
    "image":"https://picsum.photos/id/1060/400/400",
    "text":"Text about star 2"
},
{  
    "id":3,
    "name": "star 3",
    "image":"https://picsum.photos/id/1061/400/400",
    "text":"Text about star 3"
},
{  
    "id":4,
    "name": "star 4",
    "image":"https://picsum.photos/id/1062/400/400",
    "text":"Text about star 4"
},
{  
    "id":5,
    "name": "star 5",
    "image":"https://picsum.photos/id/1063/400/400",
    "text":"Text about star 5"
},
{  
    "id":6,
    "name": "star 6",
    "image":"https://picsum.photos/id/1064/400/400",
    "text":"Text about star 6"
},
{  
    "id":7,
    "name": "star 7",
    "image":"https://picsum.photos/id/1065/400/400",
    "text":"Text about star 7"
},
{  
    "id":8,
    "name": "star 8",
    "image":"https://picsum.photos/id/1066/400/400",
    "text":"Text about star 8"
},
{  
    "id":9,
    "name": "star 9",
    "image":"https://picsum.photos/id/1067/400/400",
    "text":"Text about star 9"
},
{  
    "id":10,
    "name": "star 10",
    "image":"https://picsum.photos/id/1068/400/400",
    "text":"Text about star 10"
}
]

Это отображает список в браузере

Star1
Star2
Star3
.
.
etc

Для этих элементов есть функция onClick, которая испускает объект через свойство @Output.

Затем у меня есть eventListener в теге сценария в HTML, который прослушивает это излучение и обновляет свойство src в теге img с соответствующим изображением.

Мой вопрос: Я хотел бы создать еще один WebComponent, в который встроен этот eventListener, чтобы я мог просто добавить этот второй компонент в HTML, и тогда они будут общаться друг с другом без необходимости писать eventListener непосредственно в теге скрипта. Мой текущий код.

<name-list />
<img-comp />
<img></img>  //not needed if <img-comp> can receive the emitted data
<script src="elementCommunicationWithDom.js"></script>
<script>
    init();
    function loadJSON(callback) {

        var xobj = new XMLHttpRequest();
        xobj.overrideMimeType("application/json");
        xobj.open('GET', 'data.json', true);
        xobj.onreadystatechange = function () {
            if (xobj.readyState == 4 && xobj.status == "200") {
                callback(xobj.responseText);
            }
        };
        xobj.send(null);
    }

    function init() {
        loadJSON(function (response) {
            var obj = JSON.parse(response);
            console.log(obj);
            let element = document.querySelector('name-list');
            element.names = obj; //set the html property names created in @input in Angular to the object
        });
    }

    let element = document.querySelector('name-list');
    let img = document.querySelector('img');
    // I want to do the below directly within the <img-comp> component
    element.addEventListener("onSelectItem", (event) => { //gets the output of @Output which is onSelectItem
        img.src = event.detail.image;
        console.log(event.detail.image)
    })

</script>

Вернувшись в мой компонент Angular для <img-comp>, у меня есть следующее

Шаблон

<img [src]="imgsrc" />

Составная часть

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

  @Input() imgsrc: string;


  //This below is incorrect and is what I need I think to make this work
 @HostListener('onSelectItem', ['$event'])
  OnStarClicked(event) {
  this.imgsrc = event.detail.image;
  console.log(event.detail.image);
 }  

Как мне заставить свойство @Hostlistener правильно добавить эквивалентный eventListener, который находится в теге скрипта html?

https://stackblitz.com/edit/angular-ej7fnv


person Bwizard    schedule 03.11.2019    source источник
comment
Где в приведенном выше коде вы прослушиваете событие щелчка?   -  person Rafi Henig    schedule 03.11.2019
comment
В компоненте Ngfor есть свойство @Output @Output() onSelectItem: EventEmitter<string> = new EventEmitter<string>();, а в функции onClick есть this.onSelectItem.emit(item.value);   -  person Bwizard    schedule 03.11.2019
comment
@PaulLeppard Я столкнулся с подобной проблемой, вы нашли решение для этого?   -  person divya dave    schedule 02.01.2020


Ответы (1)


Я не уверен, как выглядят ваши комонеты, но вы должны иметь в виду:

EventEmitters! == события DOM

В отличие от событий DOM, пользовательские события Angular не всплывают. Это означает, что вы можете прослушивать событие компонента только на родительском уровне.

Вы можете создать собственные события DOM следующим образом:

constructor(private el: ElementRef) { }

onClick(star) {
  this.el.nativeElement
    .dispatchEvent(new CustomEvent('onSelectItem', {
      detail: star,
      bubbles: true
    }));
}

Надеюсь, это поможет.

person Rafi Henig    schedule 03.11.2019
comment
Спасибо, Рафи, это действительно очень помогло. Я неправильно об этом думал. Я перешел на собственное событие dom, используя ваш код, но его не слышит @HostListener в компоненте <img-comp>. Есть идеи, как связать их? Спасибо - person Bwizard; 04.11.2019
comment
Мне довольно сложно ответить на него, не видя кода, можно ссылку на него разместить? - person Rafi Henig; 04.11.2019
comment
Я создал stackblitz. Имейте в виду, что он не запускается, когда я запускаю npm run build: element, который запускает ng build --prod --output-hashing none && node elements-build.js, который затем создает папку elementCommunicationWithDom в верхнем каталоге. Затем я открываю html-файл в этом каталоге, чтобы увидеть, что элементы работают (или не работают в данном случае). Спасибо, stackblitz. ru / edit / angular-ej7fnv - person Bwizard; 04.11.2019
comment
события только всплывают, ‹name-list /› и ‹img-comp /› являются узлами-братьями. - person Rafi Henig; 05.11.2019