【问题标题】:Set up an Event Listener on an Exported Angular Elements Web Component在导出的 Angular Elements Web 组件上设置事件监听器
【发布时间】:2019-11-03 18:00:10
【问题描述】:

编辑:这是一个使用 Angular Elements 从 Angular 导出的 Web 组件,不是传统的 Angular

我正在尝试使用 Angular Elements,并创建了一个加载下面 JSON 文件的 NgFor 组件。

[ 
{  
    "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 属性发出对象。

然后,我在 HTML 中的脚本标记中有一个 eventListener,它侦听此发出并使用相关图像更新 img 标记中的 src 属性。

我的问题是;我想创建另一个内置了这个 eventListener 的 WebComponent,这样我就可以将第二个组件添加到 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>

回到我的 &lt;img-comp&gt; Angular 组件中,我有以下内容

模板

<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 属性正确添加在 html 脚本标记中的等效 eventListener?

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

【问题讨论】:

  • 在上面的代码中你在哪里监听点击事件?
  • 在 Ngfor 组件中有一个 @Output 属性 @Output() onSelectItem: EventEmitter&lt;string&gt; = new EventEmitter&lt;string&gt;(); & 在 onClick 函数中有 this.onSelectItem.emit(item.value);
  • @PaulLeppard 我遇到了类似的问题,您找到解决方案了吗?

标签: javascript angular web-component angular-elements


【解决方案1】:

我不确定你的小鸟的结构是什么样的,但你必须记住:

EventEmitters !== DOM 事件

与 DOM 事件不同,Angular 自定义事件不会冒泡。这意味着你只能在父级监听组件的事件。

您可以按以下方式创建本机 DOM 事件:

constructor(private el: ElementRef) { }

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

希望对你有帮助。

【讨论】:

  • 谢谢拉菲,这确实很有帮助。我一直在错误地思考这个问题。我已使用您的代码更改为本机 dom 事件,但 &lt;img-comp&gt; 组件中的 @HostListener 没有听到它。有什么想法可以将两者联系起来吗?谢谢
  • 没看代码我很难回答,能发个链接吗?
  • 我创建了一个堆栈闪电战。请注意,当我运行 npm run build:element 时它不会运行,它运行“ng build --prod --output-hashing none && node elements-build.js”,然后在顶层目录中创建文件夹 elementCommunicationWithDom。然后我打开此目录中的 html 文件以查看元素是否正常工作(或在这种情况下不工作)谢谢stackblitz.com/edit/angular-ej7fnv
  • 事件只冒泡, 和 是兄弟节点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
相关资源
最近更新 更多