页面初始化时触发 ngb-raring 上的 rateChange

rateChange on ngb-raring fired while page is on initialization

我对 angular 很陌生, 我正在尝试使用 ngb-rating 中的 rateChange 向数据库发送一个新的 Rate,但是当它从服务器获取值时它被触发了,例如当我尝试 console.log Rate 它打印我的速率时从数据库获取。

这是 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>

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);
      }
    )
  }

}

ng-bootstrap其实是在骗我们。查看评级源代码,我看到即使用户不参与,只要更改评级值,就会发出 rateChange

我只看到一种解决方案 - 在设置初始值后利用 reactive forms. You might subscribe to the valueChanges observable

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>

您需要导入 FormModule 才能使其正常工作。

这个回答耗费了我不少时间。我确实希望它有用 (:

我创建了 an issue 来修复文档。