Angular——하위 구성 요소는 상위 구성 요소가 전달한 동적 값을 어떻게 받나요?

개발 과정에서 부모 컴포넌트가 자식 컴포넌트에 값을 전달하는 경우는 매우 흔한데, 오늘은 부모 컴포넌트가 자식 컴포넌트에 값을 전달할 때 어떤 사고가 발생할 수 있는지, 어떤 상황에서 자식 컴포넌트가 발생하는지에 대해 알아보겠습니다. 상위 구성 요소가 전달한 최신 값을 받을 수 없습니다.

전달 값:

  1. 기본 데이터 유형 : 상위 구성 요소는 기본 데이터 유형을 하위 구성 요소에 전달하고 하위 구성 요소는 변수를 사용하여 전달된 값을 받습니다. 전달된 값이 변경되면 하위 구성 요소가 받는 값도 그에 따라 변경됩니다.

  2. 참조 데이터 유형 : 상위 구성 요소가 하위 구성 요소에 전달한 데이터 객체(객체 또는 참조 유형)가 변경되면 하위 구성 요소가 받은 값이 그에 따라 반드시 변경되는 것은 아닙니다.

다음은 하위 구성 요소의 변수가 자동으로 업데이트되지 않는 몇 가지 시나리오입니다.

  1. 입력 속성이 객체 또는 참조 유형인 경우: 상위 구성 요소에서 하위 구성 요소로 전달한 입력 속성이 객체 또는 참조 유형(예: 배열)이고 객체의 속성이
    상위 구성 요소 에서 수정되거나 재할당된 경우 , 하위 구성 요소 변수 자체는 변경되지 않습니다. 변경 감지 메커니즘은 객체 또는 참조 자체 의 변경 사항만 감지할 뿐 객체 내부의 속성이나 콘텐츠의 변경 사항은 깊이 관찰하지 않습니다. 이 경우 하위 구성 요소의 변수가 업데이트되었는지 확인하기 위해 수동 처리가 필요합니다. 이는 OnChanges 수명 주기 후크를 사용하고, 입력 속성의 변경 사항을 수신하고 구독할 메서드를 설정하여 수행할 수 있습니다.
    原因:
  2. @ViewChild 또는 서비스를 사용하여 데이터 공유 : 상위 구성 요소가 @ViewChild 또는 서비스(예: 공유 서비스)를 통해 하위 구성 요소에 데이터를 전달하는 경우 일반적으로 하위 구성 요소의 변수는 자동으로 업데이트되지 않습니다. 이는 @ViewChild 또는 서비스에서 제공하는 데이터가 별도의 인스턴스이며 상위 구성 요소의 데이터와 직접적인 관련이 없기 때문입니다. 이 경우 구독 메커니즘이나 이벤트 트리거를 사용하는 등 하위 구성 요소의 변수를 수동으로 업데이트해야 합니다.

예를 들어:

1. 하위 구성 요소는 set 메서드를 사용하여 전달된 값을 받습니다.

// 父组件
@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child [data]="parentData"></app-child>
    <button (click)="changeData()">Change Data</button>
  `
})
export class ParentComponent {
    
    
  parentData = {
    
     value: 'Initial data' };

  changeData() {
    
    
    this.parentData.value = 'Updated data';
  }
}

// 子组件
@Component({
    
    
  selector: 'app-child',
  template: `<p>{
     
     { childData }}</p>`
})
export class ChildComponent {
    
    
  private _data: any;

  @Input()
  set data(value: any) {
    
    
    this._data = value;
    // 在这里可以对数据进行进一步处理
  }

  get childData(): any {
    
    
    return this._data;
  }
}

위의 예에서 상위 구성 요소는 parentData 객체를 통해 하위 구성 요소의 데이터 입력 속성에 데이터를 전달합니다. 하위 구성 요소는 set 메서드를 사용하여 이 데이터를 수신하고 이를 전용 변수 _data에 저장합니다.

"데이터 변경" 버튼을 클릭하면 상위 구성 요소의 ChangeData() 메서드가 parentData.value 값을 '업데이트된 데이터'로 수정합니다. 이때 하위 컴포넌트의 set 메소드가 트리거되고 새로운 데이터 객체 {value: 'Updated data' }가 수신됩니다. 하위 구성 요소는 set 메서드 내에서 그에 따라 데이터를 처리하여 하위 구성 요소의 상태를 업데이트할 수 있습니다.

설정된 메소드의 트리거링은 Angular의 변경 감지 메커니즘 에 의해 자동으로 처리 되므로 메소드를 수동으로 트리거할 필요가 없습니다.

메소드 트리거 타이밍 설정

  1. 초기화 중 트리거됨 : 상위 구성요소가 전달한 데이터가 하위 구성요소로 전달되면 初始化하위 구성요소의 생성 및 렌더링 프로세스 중에 set 메소드가 처음으로 트리거됩니다. 초기값을 설정하는 시간입니다.

  2. 속성 변경 시 트리거됨 : 상위 구성 요소의 데이터가 변경되면(예: 사용자 상호 작용 또는 비동기 요청 등으로 인해) Angular의 변경 감지 메커니즘은 속성 변경을 감지하고 하위 구성 요소에서 set 메서드를 트리거합니다. 하위 구성 요소의 해당 속성을 업데이트합니다.

메소드 트리거 시간 가져오기

get 메소드는 Angular의 변경 감지 메커니즘이 아닌 하위 구성요소가 속성 값을 적극적으로 읽을 때 자동으로 트리거됩니다 . 따라서 속성이 변경될 때마다 실행되지 않습니다. get 메소드는 하위 구성요소가 속성 값을 가져와야 하는 경우에만 호출됩니다.
예를 들어 보간 표현식을 사용하거나 하위 구성 요소 템플릿의 속성을 바인딩하거나 하위 구성 요소의 TypeScript 코드에 있는 속성에 직접 액세스할 때 get 메서드가 호출됩니다.

2. ngOnChanges 수명주기 후크 사용

이 후크에서는 상위 구성 요소가 전달한 입력 속성의 변경 사항을 수신하고 변경 시 하위 구성 요소 내부의 변수를 수동으로 업데이트합니다. SimpleChange 객체를 통해 새 값과 이전 값을 획득하여 비교하고 해당 처리를 수행할 수 있습니다.

// 父组件
@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child [data]="parentData"></app-child>
    <button (click)="changeData()">Change Data</button>
  `
})
export class ParentComponent {
    
    
  parentData = {
    
     value: 'Initial data' };

  changeData() {
    
    
    this.parentData.value = 'Updated data';
  }
}

// 子组件
@Component({
    
    
  selector: 'app-child',
  template: `<p>{
     
     { childData }}</p>`
})
export class ChildComponent implements OnChanges {
    
    
  @Input() data: any;
  childData: any;

  ngOnChanges(changes: SimpleChanges) {
    
    
    if (changes.data && changes.data.currentValue) {
    
    
      this.childData = changes.data.currentValue;
    }
  }
}

3. ViewChild는 static: false를 사용하여 데이터를 전달합니다.

상위 구성 요소가 @ViewChild 또는 서비스(예: 공유 서비스)를 통해 하위 구성 요소에 데이터를 전달하고 이를 사용하는 경우 static: true일반적으로 하위 구성 요소는 상위 구성 요소의 값이 변경될 때 자동으로 업데이트되지 않습니다.

대신, static: false상위 구성 요소의 값이 변경되면 하위 구성 요소도 그에 따라 업데이트됩니다.

원리: 하위 구성 요소에 대한 참조를 얻기 위해 @ViewChild를 사용할 때 static이 false로 설정된 경우 @ViewChild 는 변경 사항이 감지될 때마다 하위 구성 요소를 다시 쿼리
하는 쿼리가 됩니다 .
즉, 상위 구성 요소의 값이 변경되면 하위 구성 요소의 참조가 다시 쿼리되어 업데이트됩니다.

상위 구성 요소에서 @ViewChild를 통해 하위 구성 요소의 참조를 얻고 해당 값을 하위 구성 요소에 전달합니다.

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

@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child></app-child>
    <button (click)="updateData()">Update Parent Data</button>
  `
})
export class ParentComponent {
    
    
  @ViewChild(ChildComponent, {
    
     static: false })
  childComponent: ChildComponent;

  parentData = {
    
     name: 'John', age: 25 };

  updateData(): void {
    
    
    this.parentData = {
    
     name: 'Jane', age: 30 };
    this.childComponent.data = this.parentData;
    // 或者调用子组件的方法进行更新:this.childComponent.updateData(this.parentData);
  }
}

하위 구성 요소에서 상위 구성 요소의 값을 수신하고 해당 데이터를 템플릿에 표시하는 속성을 정의합니다.

import {
    
     Component, Input } from '@angular/core';

@Component({
    
    
  selector: 'app-child',
  template: `
    <div>Name: {
     
     { data.name }}</div>
    <div>Age: {
     
     { data.age }}</div>
  `
})
export class ChildComponent {
    
    
  @Input()
  data: any;
  
}

위의 예에서 상위 구성 요소의 updateData 메서드가 호출되면 parentData의 값을 업데이트하고 새 값을 하위 구성 요소의 data 속성에 전달합니다. @ViewChild는 static: false를 사용하므로 하위 구성 요소의 참조가 다시 쿼리되고 하위 구성 요소는 변경 감지 중에 새 값을 가져와 업데이트합니다.

요약하자면, @ViewChild를 사용하고 static: false로 설정하면 상위 구성 요소의 값이 변경되면 하위 구성 요소도 그에 따라 업데이트됩니다. 이를 통해 상위 구성 요소가 하위 구성 요소의 상태와 동작에 직접 영향을 미칠 수 있습니다.

4. ViewChild는 static: true를 사용하여 데이터를 전달합니다.

하위 구성 요소에 대한 참조를 얻기 위해 @ViewChild를 사용할 때 static이 true로 설정되면 @ViewChild를 정적 쿼리로 만들고 구성 요소가 초기화될 때 한 번만 쿼리 하게 됩니다. 이는 하위 구성 요소가 상위 구성 요소의 초기 값만 가져오고 상위 구성 요소의 값이 변경될 때 자동으로 업데이트되지 않음을 의미합니다.

이 경우 상위 구성 요소의 변경 사항을 반영하려면 하위 구성 요소의 변수를 수동으로 업데이트해야 합니다. 구독 메커니즘, 이벤트 트리거링 등을 사용하여 상위 구성 요소의 값이 변경되면 업데이트하도록 하위 구성 요소에 알릴 수 있습니다.

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

@Component({
    
    
  selector: 'app-parent',
  template: `
    <app-child></app-child>
    <button (click)="updateData()">Update Parent Data</button>
  `
})
export class ParentComponent {
    
    
  @ViewChild(ChildComponent, {
    
     static: true })
  childComponent: ChildComponent;

  parentData = {
    
     name: 'John', age: 25 };

  updateData(): void {
    
    
    this.parentData = {
    
     name: 'Jane', age: 30 };
    this.childComponent.updateData(this.parentData); // 手动更新子组件中的变量
  }
}

하위 구성 요소에서 상위 구성 요소의 값을 수신하고 해당 데이터를 템플릿에 표시하는 메서드를 정의합니다.

import {
    
     Component } from '@angular/core';

@Component({
    
    
  selector: 'app-child',
  template: `
    <div>Name: {
     
     { data.name }}</div>
    <div>Age: {
     
     { data.age }}</div>
  `
})
export class ChildComponent {
    
    
  data: any;

  updateData(newData: any): void {
    
    
    this.data = newData;
  }
}

위의 예에서는 상위 구성 요소의 updateData 메서드가 호출되면 parentData의 값을 업데이트하고 하위 구성 요소의 updateData 메서드를 수동으로 호출하여 하위 구성 요소의 변수를 업데이트합니다.

추천

출처blog.csdn.net/weixin_45678402/article/details/132149090