Renderer2 - 删除指令中的 nativeElement

Renderer2 - remove nativeElement in directive

在我的组件中,我有一个带有带有指令的选项元素的 for 循环。现在我检查指令是否有数据可用,如果没有我将从 DOM 中删除 ngOption 元素。但这不起作用......我在选项列表中看到仍然是空元素。

this.renderer.setStyle(this.el.nativeElement, 'display', 'none');

component.ts

<ng-select id="event1" style="width: 400px; padding-top: 12px" class="ml-2"
 (change)="search()" [{(ngModel)]="selectedEvent" [disabled]="blockedActionWhileLoading">
  <div *ngFor="let event of events">
    <ng-option appEventFilter [event]="event">
    </ng-option>
  </div>
</ng-select>

指令

import { Directive, ElementRef, Input, OnInit, Renderer2 } from '@angular/core';
import { TicketState } from 'src/app/tickets/ticket.model';
import { TicketService } from 'src/app/tickets/ticket.service';
import { Event } from 'src/app/verwaltung/events/event.model';
import { DatePipe } from '@angular/common';

@Directive({
  selector: '[appEventFilter]',
})
export class EventFilterDirective implements OnInit {
  @Input() event: Event;

  constructor(
    private ticketService: TicketService,
    private el: ElementRef,
    private renderer: Renderer2,
    private datePipe: DatePipe
  ) {}

  ngOnInit(): void {
    let t = this.ticketService.tickets.filter(
      (ticket) =>
        ticket.event._id === this.event._id && ticket.state === TicketState.NEW
    );

    if (t.length > 0) {
      let datePipeTimeString = this.datePipe.transform(
        this.event.date,
        'HH:mm'
      );
      let datePipeDateString = this.datePipe.transform(this.event.date);
      this.renderer.setProperty(
        this.el.nativeElement,
        'innerHTML',
        `${this.event.artist.name} - ${this.event.location.city} -
        ${this.event.location.description} -
                         ${datePipeDateString} -
                         ${datePipeTimeString}
                        `
      );
    } else {
      console.log('empty');
      this.renderer.setStyle(this.el.nativeElement, 'display', 'none');
    }
  }
}

就我个人而言,我只会在将值写入 events 或使用管道之前通过过滤来呈现包含有效数据的条目。

管道解决方案可能是这里最有趣的解决方案,因为它不会修改原始数组

filter.pipe.ts

@Pipe({ name: 'filterEvents' })
export class FilterEventsPipe implements PipeTransform {

  constructor(private ticketService: TicketService){}

  // I only assume that the type is Ticket
  transform(tickets: Ticket[]): Ticket[] {
 
    const filteredTickets = tickets.filter(ticket => {
      return this.ticketService.tickets.some(
        t => t.event.__id === ticket.event._id && t.state === TicketState.NEW
      );
    });
    return filteredTickets;

  }

}

然后使用管道如下:

<div *ngFor="let event of events | filterEvents ">
  <ng-option appEventFilter [event]="event"></ng-option>
</div>

通过这种方式,您不仅可以解决空条目的问题,还可以减少页面上 div 的数量,因为您只呈现包含相关数据的条目.

@Batajus

谢谢...这是一个很好的解决方案!...我必须将值从票证更改为事件 (EventFilter)

import { Pipe, PipeTransform } from '@angular/core';
import { Ticket, TicketState } from 'src/app/tickets/ticket.model';
import { TicketService } from 'src/app/tickets/ticket.service';
import { Event } from 'src/app/verwaltung/events/event.model';

@Pipe({ name: 'filterEvents' })
export class FilterEvents2Pipe implements PipeTransform {
  constructor(private ticketService: TicketService) {}

  // I only assume that the type is Ticket
  transform(events: Event[], tickets: Ticket[]): Event[] {
    if (!events) return;
    const filteredEvents = events.filter((e) => {
      return tickets.some((ticket) => {
        return ticket.event._id == e._id && ticket.state == 'NEW';
      });
    });

    return filteredEvents;
  }
}

另一个问题...什么更快... ngIf 还是指令? 我在 html 中有大量数据和很多 ngIf。 最好为所有这些制定一个指令?

 *ngIf="
  ticket.state === TicketState.BILLED ||
  ticket.state === TicketState.BILLEDEX ||
  ticket.state === TicketState.WRITTENOFF"