简体   繁体   English

如何计算 angular 的平均值?

[英]How can I get calculate an average in angular?

I'm trying add average reviews info when people review number of stars and then it calculate that movie have that average stars.当人们评论明星数量时,我正在尝试添加平均评论信息,然后它会计算出该电影的平均明星数。 I don't know how to get my avg caluclate in html.我不知道如何在 html 中获得我的平均计算。

Here is my HTML file:这是我的 HTML 文件:

<div *ngFor="let movie of movieData">
  <table class="table table-bordered">
    <thead>
      <tr>
        <th>Reviewer</th>
        <th>Stars</th>
        <th>Reviews</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let info of movie.reviews">
        <td>{{info.name}}</td>
        <td>{{info.stars}}</td>
        <td>{{info.comment}}</td>
      </tr>
    </tbody>
  </table>
</div>
<p>Average rating: <b> {{avgRating}} </b></p>

my DetailsComponent component:我的 DetailsComponent 组件:

export class DetailsComponent implements OnInit {
  @Input() avgRating: any;
  movieID: string;
  movieData: any;
  avg;

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private httpService: HttpService
  ) {}

  ngOnInit() {
    this.movieID = this.route.snapshot.paramMap.get("id");
    this.getOneMovie();
  }

  getOneMovie() {
    let observable = this.httpService.oneMovie(this.movieID);
    observable.subscribe((data) => {
      this.movieData = data;
    });
  }
  getMovie(idx) {
    var sum = 0;
    for (var i = 0; i < this.movieData.reviews.length; i++) {
      sum += this.movieData.reviews[i].stars;
    }
    this.avg = sum / this.movieData.reviews.length;
  }
}

and my model.js file:和我的 model.js 文件:

const ReviewSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, "Customer name is required"],
        minlength: [3, "Customer name must be a minimum of 3 characters"]
    },
    stars: {
        type: Number,
        required: [true, "Star is required"]
    },
    comment: {
        type: String,
        required: [true, "Review is required"],
        minlength: [3, "Review must be a minimum of 3 characters"]
    },
})

const MovieSchema = new mongoose.Schema({
    title: {
        type: String,
        required: [true, "Movie title is required"],
        minlength: [3, "Movie title must be a minimum of 3 characters"]
    },
    reviews: [ReviewSchema]
})

Could anybody help?有人可以帮忙吗?

There are some issues here.这里有一些问题。

First there is avgRating defined as an input:首先将 avgRating 定义为输入:

@Input() avgRating: any;

but it doesn't seem it should be an input, if it's an input you don't need to calculate it and then it's shown in the template as the same value that is get as the input.但它似乎不应该是一个输入,如果它是一个输入,你不需要计算它,然后它在模板中显示为与输入相同的值。

On the other hand, there is an avg var which is supposed to have the value of the average.另一方面,有一个avg var 应该具有平均值。 But the getMovie() method that does the maths to set the avg value seems not to be ever called.但是getMovie()方法似乎avg没有被调用过。

What it seems more logical to me would be to get rid of avgRating var and then call getMovie(idx) on getOneMovie() method when the subscription callback is executed:对我来说更合乎逻辑的是摆脱avgRating var,然后在执行订阅回调时在getOneMovie()方法上调用getMovie(idx)

  getOneMovie() {
    let observable = this.httpService.oneMovie(this.movieID);
    observable.subscribe((data) => {
      this.movieData = data;
      getMovie(idx)
    });
  }

And use this avg var in the template:并在模板中使用这个avg var:

<p>Average rating: <b> {{ avg }} </b></p>

Actually the idx parameter of getMovie(idx) seems not to be used for anything so you might also want to get rid of this parameter.实际上getMovie(idx)idx参数似乎没有用于任何事情,因此您可能还想摆脱这个参数。

If a Movie has its reviews, you can calculate the AVG as soon as you get it.如果电影有评论,您可以在得到它后立即计算 AVG。 For example:例如:

getOneMovie() {
let observable = this.httpService.oneMovie(this.movieID);
observable.subscribe((data) => {
  this.movieData = data;

  if (this.movieData.reviews != null && this.movieData.reviews.length > 0) {
    let sum = 0;
    this.movieData.reviews.forEach(review => sum += review.stars);
    this.avg = sum/this.movieData.reviews.length;
  } else {
    this.avg = 0; # Or whatever you want to show if there are no reviews for the movie
  }
});
}

The code above checks if the movie has at least 1 review in order to calculate the avg, otherwise it sets avg to 0.上面的代码检查电影是否至少有 1 条评论以计算平均值,否则将 avg 设置为 0。

Then in the template you just show it with然后在模板中你只需显示它

{{avg}}

As @jeprubio mentioned, I'd delete the Input() and getMovie(idx) as they are not being used.正如@jeprubio 提到的,我会删除Input()getMovie(idx)因为它们没有被使用。

Lastly, keep in mind that you are not initializing avg , and if getOneMovie() fails for any reason, you'll never get to set it to a number (leading to errors in the template).最后,请记住,您没有初始化avg ,如果getOneMovie()由于任何原因失败,您将永远无法将其设置为数字(导致模板出错)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM