1. 程式人生 > >【Angular】@Input和@Output

【Angular】@Input和@Output

【@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]

    結果展示:
    這裡寫圖片描述