一、需求演变及描述:
1. 有一个“客户对公司的总体评价”的字段(evalutation)。字段为枚举类型,0-5,对应关系为:0-暂无评价,1-很差,2-差,3-一般,4-好,5-很好
2. 后来需要根据评分使用星星来表现,一共5颗星,分为实星和空星,例如,当3分时,三颗星星被点亮,即3颗实星2颗空星。
二、开发前准备:
1. 用于描述星星的图标,也可以是图片,我这里使用 iconfont
2. 新建一个星级评分组件,便于复用
通过命令 ng g component rating 我新建了一个星级评分组件
三、从父组件中获取“客户对公司的总体评价”的字段的值
通常控制星星显示的 evalutation 值都是一个从父组件传递出去的Number类型值。
1、首先我们需要在调用星级组件的父组件模板中将值传递出去:
<li class="companyevalutation">客户对公司的总体评价:<app-rating [starsRating]="repairs.evalutation"></app-rating> </li>
说明:app-rating 是新建的星级评分组件,使用 starsRating 属性绑定 evalutation 的值
2、星级组件为了获得这个值,需要使用输入属性 @Input()
在星星组件的控制器(rating.component.ts)中写这样一段代码
@Input()private starsRating: number = 0;
说明:@input 用来定义模块的输入,用于从父组件向子组件传递数据
在这里可以将 starsRating 的值传递出去。
三、显示实星和空星
1. 显示5颗实星
要显示5颗实星可以这样做:
<span class="iconfont icon-start_c"></span> <span class="iconfont icon-start_c"></span> <span class="iconfont icon-start_c"></span> <span class="iconfont icon-start_c"></span> <span class="iconfont icon-start_c"></span>
但是这样的做法未免太过暴力,假如要显示100颗星,岂不是要写100行同样的代码。
显示5颗实星,可以使用 angular 的循环
<span *ngFor="let star of stars;" class="iconfont icon-start_c"></span>
同时在控制器里面,定义 stars 的值:
stars: boolean[];constructor() { }ngOnInit() {this.stars = [true, true, true, true, true]; }
这样就得到了5颗实心的星星。
star 的值为 true 时,添加 icon-start_n 类,显示空星。
<span *ngFor="let star of stars;" class="rating iconfont icon-start_c" [class.icon-start_n]="star"></span>
获取实际的星星个数:
get starsRating(): number {return this._starsRating; }@Input() set starsRating(value: number){this._starsRating = value;this.rating(); }
stars 为布尔型的数组,值为 false 将会显示实星,值为 true 将会显示空星。
public rating(): void {this.stars = [];for (let i = 1; i <= 5; i++){this.stars.push(i > this.starsRating);} }
如果 starRating 的值为 3,stars = [false, false, false, true, true]; 视图显示三颗实星,两颗空星
四、源码:
rating.component.html:
<span *ngFor="let star of stars;" class="rating iconfont icon-start_c" [class.icon-start_n]="star"></span>
rating.component.ts:
import {Component, Input, OnInit} from '@angular/core';@Component({selector: 'app-rating',templateUrl: './rating.component.html' }) export class RatingComponent implements OnInit {public _starsRating: number = 0;public stars: boolean[];get starsRating(): number {return this._starsRating;}@Input() set starsRating(value: number){this._starsRating = value;this.rating();}constructor() { }ngOnInit() {this.rating();}public rating(): void {this.stars = [];for (let i = 1; i <= 5; i++){this.stars.push(i > this.starsRating);}}}