首页 > 解决方案 > TS - '(x: HTMLElement) => void' 类型的参数不可分配给参数

问题描述

您好,提前感谢您的帮助!

使用我的第一个 Angular 页面,并正在通过一个教程来让我的垫卡动态地保持相同的高度以改变尺寸。在我的 forEach((x: HTMLElement) => 上弹出错误...请参阅下面的代码。

TS:
import { Directive, ElementRef, AfterViewChecked, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[myMatchHeight]'
})

export class MatchHeightDirective implements AfterViewChecked {
  // Class name to match height
  @Input()
  myMatchHeight: any;

  constructor(private el: ElementRef) {

  }

  ngAfterViewChecked() {
    // Call our matchHeight function here
    this.matchHeight(this.el.nativeElement, this.myMatchHeight);
  }

  @HostListener('window:resize')
  onResize() {
    // Call our matchHeight function
    this.matchHeight(this.el.nativeElement, this.myMatchHeight);
  }

  matchHeight(parent: HTMLElement, className: string) {
    // Match height logic here
    if (!parent) return;

    const children = parent.getElementsByClassName(className);

    if (!children) return;

    // Reset children height
    Array.from(children).forEach((x: HTMLElement) => {
      x.style.height = 'auto';
    });

    // Get all child el heights
    const itemHeights = Array.from(children).map(x => x.getBoundingClientRect().height);


    // Find max height
    const maxHeight = itemHeights.reduce((prev, curr) => {
      return curr > prev ? curr : prev;
    }, 0);

    // Apply max height
    Array.from(children).forEach((x: HTMLElement) => {
      x.style.height = `${maxHeight}px`;
    });
  }
}

HTML:
<div class="cards-container">
        <div myMatchHeight="mat-card" fxLayout="row wrap" fxLayoutGap="16px grid" fxLayoutAlign="center stretch">
          <div fxFlex="500px" fxFlex.xs="85%" fxFlex.md="40%">
            <mat-card fxLayout="column" fxLayoutAlign="space-between center">
              <mat-card-header>
                <mat-card-title>First M. Last</mat-card-title>
              </mat-card-header>

              <div class="image-container" fxLayoutAlign="center">
                <img src="../../assets/images/image1.jpg" />
              </div>

              <mat-card-content>
                <p>
                  I'm baby seitan tilde vape, farm-to-table in enamel pin forage reprehenderit. Retro sunt VHS
                  fingerstache, cray aliquip activated charcoal you probably haven't heard of them actually brooklyn
                  banjo labore vinyl four loko. Velit poke cupidatat pour-over nisi adipisicing master cleanse sriracha
                  lo-fi prism. Austin adipisicing duis mlkshk, occaecat hot chicken wayfarers disrupt pabst dolore
                  cold-pressed next level trust fund snackwave.
                </p>
              </mat-card-content>
            </mat-card>
          </div>

          <div fxFlex="500px" fxFlex.xs="85%" fxFlex.md="40%">
            <mat-card fxLayout="column" fxLayoutAlign="space-between center">
              <mat-card-header>
                <mat-card-title>First M. Last</mat-card-title>
              </mat-card-header>

              <div class="image-container" fxLayoutAlign="center">
                <img src="../../assets/images/image2.jpg" />
              </div>

              <mat-card-content>
                <p>
                  Hammock scenester veniam eiusmod truffaut mixtape, raw denim aesthetic. Mlkshk franzen cornhole
                  flannel. Letterpress bitters deserunt ut in ad dolor tumeric. Prism meggings brooklyn chillwave,
                  mixtape readymade salvia enamel pin fam fingerstache voluptate in man braid.
                </p>
              </mat-card-content>
            </mat-card>
          </div>
        </div>
      </div>


Error:
error TS2345: Argument of type '(x: HTMLElement) => void' is not assignable to parameter of type '(value: Element, index: number, array: Element[]) => void'.
      Types of parameters 'x' and 'value' are incompatible.
        Type 'Element' is not assignable to type 'HTMLElement'.

      Array.from(children).forEach((x: HTMLElement) => {

如果需要更多信息,请告诉我。再次感谢您的支持!

标签: angulartypescript

解决方案


document.getElementsByClassName 返回 Element 对象的 HTMLCollection。

您是否尝试过使用 Element 作为类型而不是 HTMLElement?

Array.from(children).forEach((x: Element) => { 
   if (x instanceof HTMLElement) {
     x.style.height = 'auto';
   }
});

另一种方法是使用 querySelector:

const children = parent.querySelector(`.${className}`) as HTMLElement;

if (!children) return;

Array.from(children).forEach((x: HTMLElement) => {
  x.style.height = 'auto';
});

推荐阅读