угловой способ узнать, переполняется ли содержимое контейнера в ngFor, и если да, то какой элемент запускает переполнение - PullRequest
0 голосов
/ 26 сентября 2019

Идентификатор способа узнать, не переполняют ли компоненты внутри контейнера.Если это действительно переполнение, id хотел бы получить индекс элемента, который вызывает переполнение.

Цель этой проблемы - добавить кнопку show more при ее переполнении и разбить объект на две части;предметы, которые подходят, и предметы, которые не подходят.

Компоненты создаются * ngFor.

Вот минимальный пример того, что происходит

<div class="my-container">

  <div 
    class="item"
    *ngFor="let item of items; let i = index; trackBy: trackById"
  >
    {{ item.val }}
  </div>

<div>
.my-container {
  overflow: hidden;
  max-width: 100%;
  display: flex;
}

Поскольку мой контейнер заполняется горизонтально с элементами,он может переполниться по горизонтали, если есть достаточно предметов.Я хотел бы сказать, переполняется ли он, и определить, какой элемент вызывает переполнение.

Вот моя попытка:

  // this fn gets called in ngOnChanges

  determineShowMore() {
    const container = document.querySelector('.my-container') as HTMLElement;
    const viewItems: any = container ? Array.from(viewsContainer.children) : [];

    let totalWidth = 0;

    viewItems.forEach((x: HTMLElement) => {
      totalWidth += x.offsetWidth;
    });

    const isOverflow = totalWidth > viewsContainer.offsetWidth ? true : false;

  // missing: determine which item causes the overflow
  }

Не похоже, что это работает хорошо, возможно, потому, что это происходитпрежде чем HTML полностью отображается?Я не могу запустить этот fn на ngAfterViewInit(), потому что мой items может динамически меняться, и мне нужно, чтобы он запускался при каждом изменении.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Прежде всего, я бы не стал использовать document.querySelector(), если вы используете Angular.Вы можете импортировать ElementRef и использовать его вместо этого.Во-вторых, я думаю, что вы можете достичь этого, выполняя обратный вызов каждый раз, когда добавляется один элемент.Попробуйте создать подкомпонент из одного элемента и с помощью генератора событий сообщить родителю, нужно ли добавить кнопку «Читать далее».

import { Component, ElementRef, Output, EventEmitter } from '@angular/core'

@Component({
  selector: 'single-item',
  templateUrl: './single-item.component.html',
  styleUrls: [ './single-item.component.css' ]
})
export class SingleItem {

  @Input index: number
  @Output onAddItem = new EventEmitter()

  constructor(private elementRef: ElementRef) {
    const container = this.elementRef.nativeElement
    const wrapper = this.container.parentElement
    this.onAddItem.emit({
      isOverflowed:
        container.clientHeight > wrapper.clientHeight ||
        container.clientWidth > wrapper.clientWidth,
      index: this.index:
    })
  }

}

А затем в HTML-коде родителя:

<div class="container">
  <ng-container
    *ngFor="let item of items; let i = index; trackBy: trackById"
  >
    <single-item
      (onAddItem)="handleAddItem($event)"
      [index]="i"
    >
      {{ item.val }}
    </single-item>
  </ng-container>
</div>

В JS вы можете справиться с этим следующим образом.

  overflowingIndex: number

  handleAddItem(event) {
    if (!event.isOverflowed) return false
    this.overflowingIndex = this.overflowingIndex || event.index
    // add your read more button here
  }
1 голос
/ 26 сентября 2019

Вы можете использовать API Intersection Observer для него.

Это поможет вам уведомить, является ли элемент div видимым полностью или частично.Ссылка на документы и угловая ссылка для реализации приведена ниже.

https://usefulangle.com/post/113/javascript-detecting-element-visible-during-scroll

https://blog.angularindepth.com/a-modern-solution-to-lazy-loading-using-intersection-observer-9280c149bbc

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...