5-3.Angular 入門教學 - 使用@Input將資料從父元件傳到子元件

Angular 入門教學

這個例子,因為有相關教學,所以我們先回到用4_2範例檔的程式碼進行

首先我們先創一個todo元件,將我們原先在app根元件所有的東西搬過去

ng g c todo

然後就將todo的標籤放到app.component.html上

<app-todo></app-todo>

接著再回到瀏覽器,看是否正常運作

接著我們今天要依header、section、footer切成三個元件

當然就這個例子而言,其實可以不用切,畢竟太零碎的切分,也是會造成開發及維護上的不便

但畢竟是因為例子,所以專案程度較小,為了做示範,才進行分割

所以實際上要視情況進行適度的切分元件,並不是說真的有必要切成這麼的細,這邊切成這麼細是因為要舉例子

接著我們在todo資料夾下分別產生header、section、footer三個元件

首先先來移動header部分

header.component.html

<h1>
  <div>{{title}}</div>
</h1>
<input class="new-todo" [(ngModel)]="todoInputModel" (keyup.enter)="add()" placeholder="What needs to be done????"
  autofocus>

這裡面有title、todoInputModel、add()的相關變數及程式都要搬過來header.component.ts

import { Component, OnInit } from '@angular/core';
import { Todo, TodoClass } from 'src/app/@models/todo.model';
import { TodoApiService } from 'src/app/@services/todo-api.service';
@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit {
  title = 'OneTodo';  
  todoDataList: Todo[] = [];
  todoInputModel = '';
  constructor(private todoApiService: TodoApiService) { }
  ngOnInit(): void {
  }
  add() {
    const seqno = new Date().getTime();
    const todo: Todo = new TodoClass(this.todoInputModel, false, seqno);
    this.todoDataList.push(todo);
    this.todoApiService.新增(todo).subscribe(data => {
      this.todoDataList.forEach(data2 => {
        if (data2.Seqno === seqno) {
          data2.TodoId = data.TodoId;
          data2.CanEdit = true;
        }
      })
    });
    this.todoInputModel = '';
  }
}

這時候觀察一下,哪些變數是要從父親來的在上方加入@Input(),並且把裡面的值清掉,因為要從別的地方取得

@Input()
title!: string;
@Input()
todoDataList!: Todo[];

接著我們在todo.component.html放上我們剛完成的header元件標籤

<header class="header">
  <app-header></app-header>
</header>

接著要開始傳值進去,方法也很簡單,就用屬性綁定的方式給值即可

<header class="header">
  <app-header [title]="title" [todoDataList]="todoDataList"></app-header>
</header>

如此就將我們父元件todo的title和todoDataList值傳給子元件header了

那我們可以試試看畫面的title和功能是否能正常運作

正常運作沒問題,代表父子元件有正確的進行互動了

那順帶一提,這邊的@Input也可以搭配set的用法,例如

private _title!: string;
@Input()
set title(value: string) {
  this._title = value;
};
get title() {
  return this._title.trim().toLocaleUpperCase();
}  
@Input()
todoDataList!: Todo[];

如此,進來的title都會去除空白並且大寫

那另外section和footer也是類似的作法,文章和影片就不特別示範了

想看實作流程可以看影片,完成後的程式碼,可下載範例查看

如果你照著我上面搬移的邏輯進行後,會發現刪除、切換狀態和清掉完成事項無法正確運作

這是正常的錯誤,該如何解決?可以用下一篇的@Output教學來解決

 

範例檔:下載

參考資料:  
透過輸入型繫結把資料從父元件傳到子元件 
透過 setter 截聽輸入屬性值的變化




Copyright © 凱哥寫程式 2022 | Powered by TalllKai ❤