Búsqueda de sitios web

angular - rateChange en ngb-raring se dispara mientras la página está en inicialización


Soy muy nuevo en Angular, estoy tratando de enviar una nueva tarifa a la base de datos usando rateChange en ngb-rating, pero se ha activado mientras está obteniendo los valores del servidor. Por ejemplo, cuando intento hacer console.log de la tarifa, imprime la tarifa que estoy recibiendo de la base de datos.

este es el plantillado de Html:

<div class="card-group d-flex  justify-content-center">

    <div class="row justify-content-center">

        <div *ngFor="let item of items" class="col-sm-4  card bg-light"
            style=" max-width: 17rem; border:none; display: flex;margin: 30px;">

            <div class="card-img-top" style="height: 45%; white-space: nowrap;">
                <span class="helper"></span>
                <img src="{{item.image}}" style="margin: 0px; vertical-align: middle; display: inline-block;"
                    width="100%" alt="item.Name">
            </div>
            <div class="card-body">
                <h5 class="card-title" style="text-align: center;">{{item.Name}}</h5>
                <p class="card-description" style="height: 30%;">{{item.Description | Summery}}</p>
                <h5 class="card-text  price" style=" margin: 0px 0px 20px 0px ;">{{item.price | currency}}
                </h5>
                <ngb-rating [max]='5' [(rate)]="item.stars" *ngIf="" (rateChange)="onRateChange($event)">
                    <ng-template let-fill="fill">
                        <span class="star" [class.filled]="fill === 100">&#9733;</span>
                    </ng-template>
                </ngb-rating>
            </div>
            <button class="btn btn-primary mx-auto">add to cart</button>


        </div>
    </div>
</div>

archivo ts:

import { Component, OnInit } from '@angular/core';
import { Item } from 'src/moduls/item';
import { ItemService } from './item.service';

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

export class ItemComponent implements OnInit {

  constructor(private itemService: ItemService) { }
  items: any[] = [];
  onRateChange(newRate: number) {
    console.log(newRate);
  }

  ngOnInit(): void {
    this.getItems();
  }



  getItems() {
    return this.itemService.getaData().subscribe(
      Response => {
        this.items = Response as Item[];
        console.log(this.items);
      }
    )
  }

}

Respuesta #1

El ng-bootstrap en realidad nos está mintiendo. Al mirar el código de las fuentes de calificación veo que el rateChange se emite cada vez que se cambia el valor de la calificación, incluso si el usuario no está involucrado.

Veo solo una solución: aprovechar los formularios reactivos. Podrías suscribirte al observable valueChanges después de que se establezca el valor inicial.

import { Component, OnInit, OnDescroy } from '@angular/core';
import { Item } from 'src/moduls/item';
import { ItemService } from './item.service';

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

export class ItemComponent implements OnInit, OnDestroy {
  onDestroy$: Subject = new Subject();
  items: Array<{control: FormControl, item: Item}> = [];

  constructor(private itemService: ItemService) { }

  ngOnInit(): void {
    this.getItems();
  }

  ngOnDestroy(): void {
    this.onDestroy$.next();
  }

  getItems() {
    return this.itemService.getaData().subscribe(
      Response => {
        this.items = (Response as Item[]).map(item => {
           const control = new FormControl(item.stars);
           control.valueChanges
              .tap(takeUntil(this.onDestroy$))
              .subscribe(newRate => this.saveRating(newRate,item));
           return {control, item};
        });
        console.log(this.items);
      }
    )
  }

  saveRating(newRate: number, item: Item) {
    console.log(newRate, item);
  }

}
<div class="card-group d-flex  justify-content-center">

    <div class="row justify-content-center">

        <div *ngFor="let item of items" class="col-sm-4  card bg-light"
            style=" max-width: 17rem; border:none; display: flex;margin: 30px;">

            <div class="card-img-top" style="height: 45%; white-space: nowrap;">
                <span class="helper"></span>
                <img src="{{item.image}}" style="margin: 0px; vertical-align: middle; display: inline-block;"
                    width="100%" alt="item.item.Name">
            </div>
            <div class="card-body">
                <h5 class="card-title" style="text-align: center;">{{item.item.Name}}</h5>
                <p class="card-description" style="height: 30%;">{{item.item.Description | Summery}}</p>
                <h5 class="card-text  price" style=" margin: 0px 0px 20px 0px ;">{{item.item.price | currency}}
                </h5>
                <ngb-rating [max]='5' [formControl]='item.control'>
                    <ng-template let-fill="fill">
                        <span class="star" [class.filled]="fill === 100">&#9733;</span>
                    </ng-template>
                </ngb-rating>
            </div>
            <button class="btn btn-primary mx-auto">add to cart</button>


        </div>
    </div>
</div>

Necesitarías importar FormModule para que funcione.

Esa respuesta consumió bastante tiempo. Espero que sea útil (:

Creé un problema para arreglar la documentación.

Artículos relacionados