angular - rateChange på ngb-raring utlöses medan sidan är under initiering
Jag är väldigt ny på Angular, jag försöker skicka ett nytt betyg till databasen med rateChange i ngb-rating men det har utlösts medan det hämtar värdena från servern, till exempel när jag försöker console.log betyget skriver det ut det betyg som jag får från databasen.
detta är HTML-mallen:
<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">★</span>
</ng-template>
</ngb-rating>
</div>
<button class="btn btn-primary mx-auto">add to cart</button>
</div>
</div>
</div>
ts-fil:
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);
}
)
}
}
Svar #1
Ng-bootstrap ljuger faktiskt för oss. När jag tittar på källkoden för betygskällorna ser jag att rateChange skickas ut varje gång betygsvärdet ändras, även om användaren inte är inblandad.
Jag ser bara en lösning - utnyttja de reaktiva formulären. Du kan prenumerera på valueChanges-observable efter att det initiala värdet har ställts in.
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">★</span>
</ng-template>
</ngb-rating>
</div>
<button class="btn btn-primary mx-auto">add to cart</button>
</div>
</div>
</div>
Du skulle behöva importera FormModule för att få det att fungera.
Det svaret tog ganska mycket tid. Jag hoppas verkligen att det kommer att vara användbart (:
Jag skapade ett ärende för att åtgärda dokumentationen.
