Angular组件之星级评价组件

作者: 真的稻城 | 来源:发表于2017-09-25 12:26 被阅读451次

首先上实现的步骤:

  1. 如何显示一颗星星
  2. 如何显示一个空心的星星
  3. 如何显示定义数量的星星
  4. 如何让定义数量的星星有的空心、有的实心
  5. 如何把评分数值传递到组件中,根据评分显示个数
  6. 让传递进来的值控制最大的可显示的星星数
  7. 添加点击事件来操作评分,并改变对应星星个数
  8. 当可点击之后,我们通过变量来控制是否能点击。
  9. 把点击的星星发射出去。

第一步(安装环境)

  1. cnpm install -g @angular/cli (全局安装angular-cli)
  2. ng new my-star (new 一个新项目 )
  3. cd my-star (进入刚才我们new的新项目)
  4. ng serve --open (在浏览器中打开)

第二步(引入Bootstrap样式)

  1. cnpm install bootstrap --save
  2. 在,angular-cli.json中的style中加入"../node_modules/_bootstrap@3.3.7@bootstrap/dist/css/bootstrap.min.css",(如果你是用npm下载的,那么bootstrap的包名可能会不一样,请在node_modules文件下查看)
  3. OK,这样就可以使用bootstrap的样式了.

第三步(修改app文件夹下的app.component.html文件代码)

<div style="text-align:center">
  <h1>
    <app-my-star></app-my-star>
  </h1>
  <h2>
    <span>星</span>
  </h2>
  <img width="300" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
</div>

第四步(修改my-star文件夹下的my-star.component.html文件代码)

<span>
  <span class="glyphicon glyphicon-star"></span>
</span>
//glyphicon-star是bootstrap字体样式,如果想要空心可以使用glyphicon-star-empty

第五步(修改my-star文件夹下的my-star.component.html和my-star-component.ts文件代码,实现多颗星星)

//my-star-component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-my-star',
  templateUrl: './my-star.component.html',
  styleUrls: ['./my-star.component.css']
})
export class MyStarComponent implements OnInit {

  public stars = [];

  constructor() { }

  ngOnInit() {
    this.stras = [true,true,false,true,true] 
  }
}
//my-star-component.html
<span>
  <span *ngFor="let star of stars" class="glyphicon glyphicon-star" ></span>
</span>
//通过*ngFor循环实现多颗星星

第六步(通过属性绑定class,实现空心的星星和实心的星星)

//my-star.component.html
<span>
  <span *ngFor="let star of stars" class="glyphicon glyphicon-star" [class.glyphicon-star-empty]="!star"></span>
</span>

第七步(现在我们的星星个数是我们的stars数组写死的,那么怎么把它变成可由我们自己控制的)

//在父组件中定义三个属性,rating是实心的星星数,max是最大的星星数量,readonly是是否可点击,为true时不可点击。
//app.component.html
<div style="text-align:center">
  <h1>
    <app-my-star [(rating)]="rating" [max]="max" [readonly]="readonly"></app-my-star>
  </h1>
  <h2>
    <span>{{ rating | number:'1.0-1'}}星</span>
  </h2>
  <img width="300" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
</div>
//app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  public max: number = 10;
  public rating: number = 0;
  public readonly: boolean = false;
}

//在my-star.component.ts中接收
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-my-star',
  templateUrl: './my-star.component.html',
  styleUrls: ['./my-star.component.css']
})
export class MyStarComponent implements OnInit {

  @Input()
  public rating: number;

  @Input()
  public max: number;

  @Input()
  public readonly: boolean;

  public stars = [];

  constructor() { }

  ngOnInit() {
    this.stars = [];
    for (let i = 0; i < this.max; i++) {
      this.stars.push(i < this.rating)  //rating是实心星星的个数,当rating的数值小于i的时候,往stars数组里push的就是false,星星为空心。
    }
  }
  
}

第八步(让星星实现可点击功能)

//my-star-component.html
<span>
  <span *ngFor="let star of stars; let i = index;" class="glyphicon glyphicon-star" [class.glyphicon-star-empty]="!star" (click)="onClick(i)"></span>
</span> //i 是ngFor循环的下标,通过事件绑定讲点击的是第几颗星星传入
//在my-star.component.ts中接收
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-my-star',
  templateUrl: './my-star.component.html',
  styleUrls: ['./my-star.component.css']
})
export class MyStarComponent implements OnInit {

  @Input()
  public rating: number;

  @Output()
  ratingChange: EventEmitter<number> = new EventEmitter();

  @Input()
  public max: number;

  @Input()
  public readonly: boolean;

  public stars = [];

  constructor() { }

  ngOnInit() {
    //重新清空数组
    this.stars = [];
    for (let i = 0; i < this.max; i++) {
      this.stars.push(i < this.rating)
    }
  }

  onClick(rate: number) {
    //如果readonly不为true时,
    if( !this.readonly ){
      //因为数组是从0开始,星星的个数不可能是0个,所以rate + 1
      this.rating = rate + 1; 
      this.ngOnInit();
    }
  }

第九步(根据点击,实时显示有多少颗星星)

//app.component.html
<div style="text-align:center">
  <h1>
    <app-my-star [(rating)]="rating" [max]="max" [readonly]="readonly"></app-my-star>
  </h1>
  <h2>
    <span>{{ rating | number:'1.0-1'}}星</span>
  </h2>
  <img width="300" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxOS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAyNTAgMjUwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAyNTAgMjUwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojREQwMDMxO30NCgkuc3Qxe2ZpbGw6I0MzMDAyRjt9DQoJLnN0MntmaWxsOiNGRkZGRkY7fQ0KPC9zdHlsZT4NCjxnPg0KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTI1LDMwIDEyNSwzMCAxMjUsMzAgMzEuOSw2My4yIDQ2LjEsMTg2LjMgMTI1LDIzMCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAJIi8+DQoJPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIxMjUsMzAgMTI1LDUyLjIgMTI1LDUyLjEgMTI1LDE1My40IDEyNSwxNTMuNCAxMjUsMjMwIDEyNSwyMzAgMjAzLjksMTg2LjMgMjE4LjEsNjMuMiAxMjUsMzAgCSIvPg0KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMjUsNTIuMUw2Ni44LDE4Mi42aDBoMjEuN2gwbDExLjctMjkuMmg0OS40bDExLjcsMjkuMmgwaDIxLjdoMEwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMUwxMjUsNTIuMQ0KCQlMMTI1LDUyLjF6IE0xNDIsMTM1LjRIMTA4bDE3LTQwLjlMMTQyLDEzNS40eiIvPg0KPC9nPg0KPC9zdmc+DQo=">
</div> //通过数据双向绑定在span标签中绑定rating。

//my-star.component.ts
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-my-star',
  templateUrl: './my-star.component.html',
  styleUrls: ['./my-star.component.css']
})
export class MyStarComponent implements OnInit {

  @Input()
  public rating: number;

  @Output()
  ratingChange: EventEmitter<number> = new EventEmitter(); 

  @Input()
  public max: number;

  @Input()
  public readonly: boolean;

  public stars = [];

  constructor() { }

  ngOnInit() {
    this.stars = [];
    for (let i = 0; i < this.max; i++) {
      this.stars.push(i < this.rating)
    }
  }

  onClick(rate: number) {
    if( !this.readonly ){
      //因为数组是从0开始,
      this.rating = rate + 1; 
      this.ngOnInit();
      this.ratingChange.emit(this.rating);
    }
  }

}
// 通过@Output,声明一个输出口属性。在通过emit用来发射值

OK,大功告成!

相关文章

  • Angular组件之星级评价组件

    首先上实现的步骤: 如何显示一颗星星 如何显示一个空心的星星 如何显示定义数量的星星 如何让定义数量的星星有的空心...

  • Angular组件篇

    Angular组件 一:组件基础 1:什么是组件? 组件(Component)是构成Angular应用的基础和核心...

  • angular内置指令相关知识

    大纲 1、angular指令的分类2、angular指令之——组件3、angular指令之——属性指令 (ngSt...

  • vue实现店铺的星级评价

    需求分析#### 1.星级评价在店铺中多次使用,因此作为组件进行编写2.星级评价的标准是该店铺的得分,样式以星星的...

  • 样式封装&组件间通信

    关于样式 angular 可以将样式封装在组件本身中,不会影响其他组件的样式(默认)Angular 会修改组件的 ...

  • Angular2+ 如何向不关联组件传入数据

    关键词 Angular2+ 前言 众所周知,Angular2+向子组件传递数据用@Input(), 子组件向父组件...

  • Angular 5 自定义文件上传组件(四)

    Angular 5 自定义文件上传组件(一)Angular 5 自定义文件上传组件(二)Angular 5 自定义...

  • Angular4~6 视图操作方式以及组件的变化检测过程

    Angular 应用由组件树构成,组件树由多个视图和子视图构成,而视图是构成 Angular 组件的基本元素,同时...

  • Angular 入门

    Angular介绍 Angular安装、创建项目、目录结构、组件、服务 创建组件、绑定数据、绑定属性、数据循环、条...

  • Angular组件介绍

    1.背景介绍 Angular组件的必备元素 1.组件元数据装饰器:@Component() 告诉angular如何...

网友评论

本文标题:Angular组件之星级评价组件

本文链接:https://www.haomeiwen.com/subject/jpgrextx.html