gpt4 book ai didi

javascript - 如何在没有querySelector的情况下在Angular中获取动态生成的元素?

转载 作者:行者123 更新时间:2023-12-05 00:39:10 25 4
gpt4 key购买 nike

我目前正在创建自己的 toastr 服务,如下面的 GIF 所示

enter image description here

我要达到的目标
https://stackblitz.com/edit/angular-ivy-tgm4st?file=src/app/app.component.ts
但没有查询选择器。根据我的阅读,您不应该使用 queryselector 以 Angular 检索 DOM 中的元素

问题
每当我单击 CTA 按钮时,我都会将一个 toast 元素添加到该组件订阅并用于更新 DOM 的 toast 数组中。
toast 是这样生成的:

export class ToastComponent implements OnInit {
constructor(private toast: ToastService, protected elementRef: ElementRef) {}

toasts = this.toast.Toasts;
  <div
class="toast-wrapper wobble-animation"
*ngFor="let t of toasts.value"
(click)="DestroyToast(t, $event)"

我想要的
我想在“动画结束”时向 toast 添加一个事件监听器来破坏 HTML 元素。单击这行代码时,我已经这样做了:
       DestroyToast(element, event): void {
event.target.classList.remove('wobble-animation');
event.target.classList.add('slide-out-animation');
event.target.addEventListener('animationend', () => {
this.toasts.value.splice(this.toasts.value.indexOf(element), 1);
});
}
我最初的想法是订阅数组并将其用作事件监听器,以便在推送某些内容时使用。然后,我将使用一个函数来获取最新的 toast 并添加另一个事件监听器,即“animationend”事件监听器。
我试过这样的方法:
  ngOnInit(): void {
this.toast.Toasts.subscribe((args) => {
this.UpdateToasts();
});
}
UpdateToasts() {
let toastElements = document.querySelectorAll('.toast');
console.log(toastElements);
}
但不幸的是,它太慢了,并且总是在第一个事件上返回 null。
enter image description here

我认为我已经读过在 Angular 中使用 querySelector 通常是不好的做法。所以问题是:
如何在没有querySelector的情况下在Angular中获取动态生成的元素?

完整代码
Toast.Component.ts
import { ToastService } from './../../services/toast.service';
import { toast } from './toast.model';
import { Component, OnInit, ElementRef } from '@angular/core';
import { Observable } from 'rxjs';

@Component({
selector: 'app-toast',
templateUrl: './toast.component.html',
styleUrls: ['./toast.component.scss'],
})
export class ToastComponent implements OnInit {
constructor(private toast: ToastService, protected elementRef: ElementRef) {}

toasts = this.toast.Toasts;
ngOnInit(): void {
this.toast.Toasts.subscribe((args) => {
this.UpdateToasts();
});
}
ngOnDestroy() {
this.toasts.unsubscribe();
}
DestroyToast(element, event): void {
event.target.classList.remove('wobble-animation');
event.target.classList.add('slide-out-animation');
event.target.addEventListener('animationend', () => {
this.toasts.value.splice(this.toasts.value.indexOf(element), 1);
});
}
UpdateToasts() {
let toastElements = document.querySelectorAll('.toast');
console.log(toastElements);
}
}
Toast.Component.html
<div class="toast-container">
<div
class="toast-wrapper wobble-animation"
*ngFor="let t of toasts.value"
(click)="DestroyToast(t, $event)"
>
<div
class="toast default"
[ngClass]="{ 'slide-out-animation': t.TimeLeft < 1 }"
>
<div class="notification-count" *ngIf="t.Count > 1">
{{ t.Count }}
</div>
<div class="content-container">
<p class="title">
{{ t.Title }}
</p>
<p class="content">{{ t.Content }}</p>
</div>
<span class="progress">
<span
class="real-progress"
[ngStyle]="{ 'width.%': t.PercentageCompleted }"
></span>
</span>
</div>
</div>
</div>
Toast.Service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { toast } from '../components/toast/toast.model';

@Injectable({
providedIn: 'root',
})
export class ToastService {
public Toasts = new BehaviorSubject<Array<object>>([]);

constructor() {}

Toast(Title: string, Message?: string, Style?: string, Timer?: number) {
const toastModel = new toast({
Title: Title,
Content: Message,
Timer: Timer,
Style: Style,
TimeLeft: Timer,
Count: 1,
PercentageCompleted: 100,
});
this.AddToast(toastModel);
}

private AddToast(toast: toast) {
const currentArr = this.Toasts.value;
const updatedToast = [...currentArr, toast];
let timer = setInterval(function () {
toast.PercentageCompleted = toast.TimeLeft / (toast.Timer / 100);
toast.TimeLeft = toast.TimeLeft - 10;
if (toast.TimeLeft <= 0 || !toast.TimeLeft) {
clearInterval(timer);
}
}, 10);
this.Toasts.next(updatedToast);
}
}
链接到带有实时代码的网站 ModernnaMedia

最佳答案

我不是 100% 确定我理解正确,似乎有两个 animationend正在发生的事件。

I want to add an eventlistener to the toast whenever 'animationend' to destroy the HTML element.


您可以直接在模板中绑定(bind)它:
<div
*ngFor="let toast of toasts"
#toastEl
(animationend)="DestroyToast(toastEl)"
class="toast">
</div>
DestroyToast(toastEl: HTMLElement) {
// …
}

关于javascript - 如何在没有querySelector的情况下在Angular中获取动态生成的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70138110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com