【Angular】@Input和@Output

该篇是上一篇的改编:【Angular】table假分页

【@Input和@Output】

@Input和@Output这两个要结合父组件与子组件来说

  • @Input:是属相绑定,父组件向子组件传递数据
  • @Output:是事件绑定,子组件向父组件传递数据的同时触发事件

【举例说明】

testtable是父组件,datatable是子组件
这里写图片描述
      主要功能:table实现分页显示,点击删除按钮时删除数据。为了更好的解耦,比如当页数改变或标题改变时,不去改动主要实现代码,只需改变父组件的页数或标题即可,就满足了需求的改变。

//testtable.component.ts
export class TesttableComponent implements OnInit {

  values = ["","#","First Name","Last Name","User Name","操作"];
  attributeValues = ["id","FirstName","LastName","UserName"];

  Users=[
    { id: 1, FirstName: 'wang',LastName:'shuang',UserName:'1' },
    { id: 2, FirstName: 'li',LastName:'hua',UserName:'2' },
    { id: 3, FirstName: 'zhao',LastName:'nan',UserName:'3'},
    { id: 4, FirstName: 'niu',LastName:'qian',UserName:'4' },
    { id: 5, FirstName: 'yan',LastName:'wen',UserName:'5' },
    { id: 6, FirstName: 'liu',LastName:'wen',UserName:'6' },
    { id: 7, FirstName: 'bai',LastName:'jing',UserName:'7' },
    { id: 8, FirstName: 'an',LastName:'jing',UserName:'8'},
    { id: 9, FirstName: 'wei',LastName:'yuan',UserName:'9' },
    { id: 10, FirstName: 'kou',LastName:'ru',UserName:'10' },
  ];

  //页号
  page:number;  
  //总记录数     
  total:number;       
  //页的大小
  pageSize:number;  
    //总页数
  totalPages:number;

  constructor() { }

  ngOnInit() {
    this.page=1;
    this.pageSize=4;
    this.total=this.Users.length;
    this.totalPages=this.total/this.pageSize; 
  }

  //el:选中的索引
  doRealDelete(el:any){
     for(let i=0;i<el.length;i++){
        this.Users.splice(el[i]-i,1);  
     }
  }
}

【注释】

  •        为什么要在ngOnInit()中赋值:查了查Angular的官网是这样说的: 在Angular第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件,在第一轮ngOnChanges()完成之后调用,只调用一次。我就简单粗暴的这样记了:用于初始化。所以赋值写在了ngOnInit()中。如果在全局变量中将一个表达式的值赋值给变量时很可能会出错
  • this.Users.splice(el[i]-i,1):el是子组件传过来的选中行的索引值,但在每次删除时User的数量就会减一,及所以就会减一,如果还按原来的索引减,就不行了,要在原来的索引上都先去已删除的个数,这样索引就变为删除之后的索引了,这样删除成功
//testtable.component.html
<app-datatable [titles]="values" [attribute]="attributeValues" [users]="Users" [page]="page" [pageSize]=pageSize [total]=total [totalPages]=totalPages (doDelete)="doRealDelete($event)">
</app-datatable>

【注释】

  • <app-datatable>是子组件的选择器
  • 通过[变量]向子组件传递数据
    • [titles]=”values”:valuse是父组件中的一个变量,复制给titles,然后在子组件中用@Input() titles来接收传过来的值,名称必须一致
  • (doDelete)是子组件传过来的触发事件,名称必须一致,(doDelete)事件又由doRealDelete()来触发
//testtable.module.ts
import { DatatableComponent  } from '../datatable/datatable.component';  //导入子组件
@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    RouterModule.forChild(TesttableRoutes)
  ],
  declarations: [TesttableComponent,DatatableComponent]
})
export class TesttableModule { }

【注释】

  • 必须在父组件中导入子组件
//datatable.component.ts 在上一篇上添加如下内容
export class DatatableComponent implements OnInit {

  @Input() titles;
  @Input() attribute;
  @Input() users:string[][]=new Array();
  @Input() page:number;
  @Input() total:number;
  @Input() pageSize:number;
  @Input() totalPages:number;
  @Output() doDelete= new EventEmitter<any>(); 

  checked=new Array<boolean>();//是否被选中

  constructor() {}

  ngOnInit() {

  }

  //选中行
  select(i:number,ckbox:HTMLInputElement){
    this.checked[i] = ckbox.checked;
  }
  //删除选中行
  deleteDatas(){
    let isDelete = false;
    //let ids = new Array<string>();  //存放选中的索引
    let dataCount = new Array();
    for (let j=0;j<this.checked.length;j++){
      if(this.checked[j]){
        dataCount.push(j);  //选中的索引
        isDelete = true;    //标识有无选中的
      }
    }
    if(!isDelete){
      alert("请至少选中一条记录");
      return;
    }
    this.doDelete.emit(dataCount);//给父组件选中的索引
  }

  //初始化,设为初始态都为false,未选中
  disposeChecked(){
    this.checked.length = this.users.length;
    for (let i = 0; i < this.users.length; i++) {
      this.checked[i] = false;
    }
  }
}

【注释】

  • Math.ceil():是个向上取整函数当,此处必须有,否则会出现类似2.5页的情况
  • @Output() doDelete= new EventEmitter(); 创建一个事件源,当执行deleteDatas()就会触发该事件源,然后让父组件执行此方法
  • @Input() 来接受父组件传过来的值
<!--在上 一篇博客的基础上,在html上添加一个删除按钮 -->
<div>
  <button (click)="deleteDatas()">删除</button>
</div>
@NgModule({
  imports: [
    CommonModule,
    FormsModule
  ],
  declarations: [DatatableComponent],
  exports:[DatatableComponent]  //导出组件
})

【注释】

  • 要想别人用你的组件,必须将自己的组件导出 exports:[DatatableComponent]

    结果展示:
    这里写图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Angular中的@Input和@Output是用来实现组件之间通信的注解。 @Input用来接收父组件传递过来的数据,而@Output则用来向父组件传递数据。 下面是它们的使用方法: 1. @Input 在子组件中使用@Input注解来接收父组件传递的数据。例如: ``` import { Component, Input } from '@angular/core'; @Component({ selector: 'child-component', template: ` <div>{{data}}</div> ` }) export class ChildComponent { @Input() data: string; } ``` 在父组件中使用属性绑定的方式将数据传递给子组件。例如: ``` import { Component } from '@angular/core'; @Component({ selector: 'parent-component', template: ` <child-component [data]="myData"></child-component> ` }) export class ParentComponent { myData = 'Hello world'; } ``` 2. @Output 在子组件中使用@Output注解来定义一个事件。例如: ``` import { Component, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'child-component', template: ` <button (click)="onClick()">Click me</button> ` }) export class ChildComponent { @Output() clicked = new EventEmitter<void>(); onClick() { this.clicked.emit(); } } ``` 在父组件中使用事件绑定的方式监听子组件的事件。例如: ``` import { Component } from '@angular/core'; @Component({ selector: 'parent-component', template: ` <child-component (clicked)="onChildClicked()"></child-component> ` }) export class ParentComponent { onChildClicked() { console.log('Child component clicked'); } } ``` 这样就实现了子组件向父组件传递数据的功能。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值