jeudi 7 juillet 2022

Random function makes component change on click

I am creating a "Pinterest" view in an Angular app. I want each tile to have a random height from 250px to 450px with a 50px step for each possible height. The problem I have is each time i click on the list of tiles (CardComponent), the function randomSize() resets tiles and change their height indefinitely. Check the end of the post to play with the Stackblitz that I've provide you :)

This is way I'm currently handling this :

DomainDetailsComponent.ts

export class DomainDetailsComponent implements OnInit {

  domain$!: Observable<DomainModel>;
  private domainId: any;
  catArray: CategoryModel[][] = [];

  constructor(
    private domainService: DomainsService,
    private route: ActivatedRoute) {
    this.route.paramMap.subscribe(params => {
      if (params.has('domainId')) {
        this.domainId = params.get('domainId');
        this.domain$ = this.domainService.getDomainById(this.domainId).pipe(map((res) => {
          let domain = res.data[0];
          if (domain && domain.categories?.length)
            this.divideArray(domain.categories, domain.categories.length / 3);
          return domain
        }));
      }
    })
  }

  ngOnInit(): void {

  }

  divideArray(arr: CategoryModel[], spliceAt: number) {
    while (arr.length) {
      let str = (arr.splice(0, spliceAt));
      this.catArray.push(str);
    }
    const average = this.catArray.reduce((a, b) => a + b.length, 0) / this.catArray.length;

    for (let j = 0; j < this.catArray.length; j++) {
      let line = this.catArray[j]
      if (line.length > average) {
        // Retrieve average+ indexes
        let overElts = line.slice(average - 1, this.catArray.length - average)
        // Remove them from the actual line
        this.catArray[j] = line.slice(0, average)
        // Moving them to the next line
        this.catArray[j + 1] = this.catArray[j + 1].concat(overElts);
      }
    }
  }

  randomSize(): number {
    let numbers = [250, 300, 350, 400, 450];
    let index = Math.floor(Math.random() * numbers.length)
    return numbers[index];
  }
}

DomainDetailsComponent.html


<div class="grid_row" *ngIf="catArray.length > 0">
    <ng-container *ngFor="let line of catArray">
      <div class="grid_column">
        <app-card *ngFor="let cat of line" [category]="cat" [maxWidth]="450" [maxHeight]="randomSize()"></app-card>
      </div>
    </ng-container>
  </div>

CardComponent.ts


import {Component, HostListener, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {CategoryModel} from "../../models/CategoryModel";
import {ProjectModel} from "../../models/ProjectModel";
import {SiteModel} from "../../models/SiteModel";

@Component({
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit, OnChanges {

  @Input()
  category?: CategoryModel;
  @Input()
  descLimit?: number = 20;
  @Input()
  allowRedirect: boolean = true;
  @Input()
  maxWidth?: number = 250;
  @Input()
  maxHeight?: number = 300;

  constructor() {
  }

  ngOnInit(): void {
  }

  @HostListener("click", ["$event"])
  public onClick(event: any): void {
    if (!this.allowRedirect)
      event.stopPropagation();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['maxHeight'].firstChange && changes['maxHeight'] && changes['maxHeight'].previousValue !== changes['maxHeight'].currentValue) {
      this.maxHeight = changes['maxHeight'].currentValue;
    } else {
      return;
    }
  }
}

CardComponent.html

<ng-container *ngIf="category !== undefined">
  <div class="element" style="max-width:">
    <figure class="element__thumb" style="max-height:">
      <img src="" alt="" class="element__image">
      <figcaption class="element__caption">
        <h2 class="element__title"></h2>
        <p class="element__snippet"></p>
        <a [routerLink]=" this.allowRedirect ? ['/categories', category.id] : null" class="element__button">En
          savoir plus</a>
      </figcaption>
    </figure>
  </div>
</ng-container>

Im asking for help fixing this behavior !

Here is a StackBlitz editor for you to play with that reproduces the bug and here is the StackBlitz App

Thanks for your time and I hope you will find this picky problem




Aucun commentaire:

Enregistrer un commentaire