通过@ViewChildern通过自定义属性选择html元素后无法调用Primeng方法的方法

问题描述 投票:0回答:1

我正在使用 Angular 框架 Primeng p-carousel 来显示一些词汇卡。在词汇卡上,我使用 p-inplace 隐藏一些信息,在用户尝试解决问题之前,这些信息仍然隐藏。我为每个 p-inplace 分配了一个自定义唯一属性

wordId
,以便访问每个特定的 p-当用户单击 p-inplace 的显示按钮时就地,因为默认情况下 Primeng Inplace 总是在单击事件后显示隐藏信息,但我想检查用户是否已尝试解决问题,如果没有,请单击“赢”不触发Inplace显示信息。HTML代码如下所示:

<p-carousel [value]="words2Learn" [numVisible]="1" [numScroll]="1" [showNavigators]="false"
                [showIndicators]="false" [page]="wordIdx" itemStyle="width:100%">
                <ng-template let-word pTemplate="item">
                    <p-fieldset legend={{word.wordDto.bookNameCh}}
                        class="card flex flex-column md:flex-row md:align-items-center justify-content-around">
                        <div>
                            <p class="mb-1 font-black text-6xl">{{ word.wordDto.wordName }}</p>
                        </div>
                    </p-fieldset>
                    <p-fieldset legend="Details">
                        <p-accordion [activeIndex]="[0,1,2,3,4,5]" [multiple]="true">
                            <p-accordionTab *ngIf="word.wordDto.remMethods.length > 0" [disabled]=" detailsDisabled"
                                header="Remember Method">
                                <p-inplace #rem [active]="showRem" [attr.wordId]="word.wordDto.id"
                                    (onActivate)="showDetails($event, 'rem',word.wordDto.id)">
                                    <ng-template pTemplate="display">
                                        <i class="pi pi-lock flex justify-content-center" style="font-size: 3rem"></i>
                                    </ng-template>
                                    <ng-template pTemplate="content">
                                        <span
                                            class="font-bold flex justify-content-center">{{word.wordDto.remMethods[0].method}}</span>
                                    </ng-template>
                                </p-inplace>
                            </p-accordionTab>
                        </p-accordion>
                    </p-fieldset>
</p-carousel>

我知道Inplace的

activate()
deactivate()
方法可以显示和隐藏,所以我想根据条件手动决定是否显示信息,而这里的条件并不重要,说它是一个可以通过某种逻辑分配的简单布尔变量。我尝试使用
(onActivate)
钩子来捕获单击事件,并将函数
showDetails($event, 'sen', word.wordDto.id)
传递给它。其中
word.wordDto.id
也是当前 p-inplace 的自定义属性
[attr.wordId]
,因此我可以使用它来定位正在单击的 p-inplace。在
showDetails()
内部,我试图通过使用elementRef和@ViewChildern以及属性[attr.wordId]来找到当前的p-inplace,虽然我可以访问正确的p-inplace,但问题是我找不到方法唤起
activate(event)
deactivate(event)
功能。

.ts代码如下所示:

export class DashboardComponent implements OnInit, OnDestroy {

    @ViewChild('usPhoneUrl') usPhone!: HTMLAudioElement
    @ViewChildren('rem', { read: ElementRef }) rem!: QueryList<ElementRef>

    showDetails(event: Event, component: string, wordId: string) {
        if (!this.haveTried) {
            this.messageService.add({ severity: 'warn', summary: 'Warn', detail: "Try first!" });
            switch (component) {
                case 'rem':
                   (this.rem.toArray()
                        .filter(x => x.nativeElement.getAttribute('wordId') === wordId)[0]
                        .nativeElement as Inplace).deactivate(event);
                    break;
                ......
                default:
                    break;
            }
        }

注意

this.haveTried
是唤起
activate()
deactivate()
的条件。

浏览器的错误是:

TypeError: this.cog.toArray(...).filter(...)[0].nativeElement.deactivate is not a function

看起来

as Inplace
没有完成转换工作。当我尝试
console.log(XXX.nativeElement as Inplace)
时,我仍然得到 html 元素而不是 Inplace 实例,我想这就是我无法访问该方法的原因。

我也尝试过

@ViewChildren('rem', { read: Inplace }) rem!: QueryList<Inplace>
,通过这种方式我可以获得一组Inplace实例,并为每个实例调用
activate()
deactivate()
,但是如何过滤正确的p-inplace html元素呢?

我已经尽力了,任何人都可以帮忙!

顺便说一句,我正在使用

"primeng": "17.18"

"@angular/animations": "^17.0.5",
        "@angular/cdk": "^17.0.2",
        "@angular/common": "^17.0.5",
        "@angular/compiler": "^17.0.5",
        "@angular/core": "^17.0.5",
        "@angular/forms": "^17.0.5",
        "@angular/platform-browser": "^17.0.5",
        "@angular/platform-browser-dynamic": "^17.0.5",
        "@angular/router": "^17.0.5",
angular typescript primeng
1个回答
0
投票

您可以简单地将模板引用变量作为参数传递给函数,然后调用 deactivate 函数。下面是工作演示。

TS:

import { Component } from '@angular/core';
import { ImportsModule } from './imports';
import { Inplace } from 'primeng/inplace';
@Component({
  selector: 'inplace-basic-demo',
  templateUrl: './inplace-basic-demo.html',
  standalone: true,
  imports: [ImportsModule],
})
export class InplaceBasicDemo {
  showDetails(event: any, rem: Inplace) {
    console.log(event, rem);
    alert('cannot open this!');
    rem.deactivate(event);
  }
}

HTML:

<div class="card">
  <p-inplace #rem (onActivate)="showDetails($event, rem)">
    <ng-template pTemplate="display">
      <span>View Content</span>
    </ng-template>
    <ng-template pTemplate="content">
      <span
        >Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
        tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
        veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
        commodo consequat. Duis aute irur e dolor in reprehenderit in voluptate
        velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
        occaecat cupidatat non proident, sunt in culpa qui officia deserunt
        mollit anim id est laborum.</span
      >
    </ng-template>
  </p-inplace>
</div>

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.