angular 組件間傳值與通信的方法

1 環境搭建

  安裝 Angular CLI

npm install -g @angular/cli

ng new my-app

cd my-app

npm start/ng serve --open

ng serve 命令會啓動開發服務器、監視文件,並在這些文件發生更改時重建應用。

--open(或者只用 -o 縮寫)選項會自動打開你的瀏覽器,並訪問 http://localhost:4200/

2 頁面創建

ng generate component view/home

ng generate component view/child


3 參數傳遞

方法1 @Input 父級組件向子組件傳遞

父級組件home.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {ChildComponent} from '../child/child.component'; 

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {  
  goChild = '23456' 
  constructor() { }  

  ngOnInit() { } 

}

父級組件home.html.ts

<app-child [fromParentData]="goChild" (changeNumber)="onListen($event)"></app-child>

app-child是在home.component.ts生成組件時,默認生成的。下邊代碼的selector

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})

子組件 child.component.ts


import { Component, OnInit, Output, Input } from '@angular/core';
import {Injectable,EventEmitter} from '@angular/core'; 

import {HomeService} from '../../service/home.service'

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() fromParentData; 
  constructor() {}

  ngOnInit() {
     console.log(this.fromParentData)
  } 

}

方法 2 EventEmitter, @output 子組件傳遞消息給父組件  

子組件創建事件 EventEmitter 對象,使用@output公開出去
父組件監聽子組件@output出來的方法,然後處理事件 

home.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {ChildComponent} from '../child/child.component'; 

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

  ngOnInit() { }

  onListen(arg){
    console.log(arg)
  }

}

home.component.html

<app-child [fromParentData]="goChild" (changeNumber)="onListen($event)"></app-child>

child.component.ts


import { Component, OnInit, Output, Input } from '@angular/core';
import {Injectable,EventEmitter} from '@angular/core';  

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() fromParentData;

  @Output() changeNumber: EventEmitter<number> = new EventEmitter(); 
  constructor(private message:HomeService ) {}

  ngOnInit() {

    console.log(this.fromParentData)
        this.changeNumber.emit(1)
  } 

}

方法3 使用 @ViewChild

一般用於父組件給子組件傳遞信息,或者父組件調用子組件的方法

home.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {ChildComponent} from '../child/child.component'; 

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit { 
  @ViewChild(ChildComponent, {static: false}) child:ChildComponent; 
  constructor() { } 

  ngAfterViewInit() {
    this.child.getData();
  }  

}

home.component.html

<app-child></app-child>

child.component.ts


import { Component, OnInit, Output, Input } from '@angular/core';
import {Injectable,EventEmitter} from '@angular/core';  

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

  ngOnInit() {}

  getData(){
    console.log('child methods')
  }

}

方法4 service進行通訊,兩個組件同時注入某個服務

爲什麼需要服務?

組件不應該直接獲取或保存數據,它們不應該瞭解是否在展示假數據。 它們應該聚焦於展示數據,而把數據訪問的職責委託給某個服務。

@Injectable() 服務

@Injectable()裝飾器。 它把這個類標記爲依賴注入系統的參與者之一

provide

在要求 Angular 把服務 注入到組件之前,你必須先把這個服務提供給依賴注入系統。默認情況下,Angular CLI 命令 ng generate service 會通過給 @Injectable 裝飾器添加元數據的形式,用根注入器將你的服務註冊成爲提供商。

@Injectable({
  providedIn: 'root',
})

新建一個服務home.service.ts,組件home和組件child同時注入該服務
組件home從服務獲取數據,或通過服務傳遞數據
組件child從服務獲取數據,或通過服務傳遞數據 

創建home.service.ts

ng generate service service/home
import { Injectable } from '@angular/core';

import { Observable, of } from 'rxjs'; 

@Injectable({
  providedIn: 'root'
})
export class HomeService { 

  messages: string[] = ['12'];

  add(message: string) {
    console.log(message)
    this.messages.push(message);
  }

  getMessage():Observable<any> {
    return of(this.messages);
    // return {this.messages}
  }  

}

home.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import {ChildComponent} from '../child/child.component';
 
import {HomeService} from '../../service/home.service'

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {  
  
  arr : string[] = [];
  constructor(private message:HomeService) { }  

  ngOnInit() {
    this.arr = this.message.getMessage();
    console.log(this.arr)
  } 

}

child.component.ts


import { Component, OnInit, Output, Input } from '@angular/core';
import {Injectable,EventEmitter} from '@angular/core'; 

import {HomeService} from '../../service/home.service'

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  
  constructor(private message:HomeService ) {}

  ngOnInit() {  

    //組件發送消息3
    this.message.add('3');
    // 組件接收消息
    const b = this.message.getMessage();
    console.log('組件接收消息'+b)
  } 

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章