> 웹 프론트엔드 > JS 튜토리얼 > Angular2에서 부모-자식 구성 요소 통신을 구현하는 방법

Angular2에서 부모-자식 구성 요소 통신을 구현하는 방법

亚连
풀어 주다: 2018-06-09 10:37:10
원래의
1977명이 탐색했습니다.

이 기사에서는 주로 Angular2 상위-하위 구성 요소 통신 방법의 예를 소개하고 참고용으로 제공합니다.

Angular2 공식 문서에는 구성 요소 상호 작용-->문서--구성 요소 간 상호 작용에 대한 자세한 소개가 있습니다. 문서에 따르면 구성 요소 간에 상호 작용하는 방법에는 다음을 포함하여 4가지가 있습니다.

  1. 입력 바인딩(@Input 장식)을 통해 상위 구성 요소에서 하위 구성 요소로 데이터를 전송합니다. 하위 구성 요소는 EventEmitter 속성(@Output 장식)을 노출합니다. 이벤트가 발생하면 이 속성을 사용하여 상위 구성 요소에 이벤트를 내보냅니다.

  2. 상위 구성 요소와 하위 구성 요소는 지역 변수를 통해 상호 작용합니다. (#var)

  3. 상위 구성 요소는 @ViewChild를 호출합니다.

  4. 상위 구성 요소와 하위 구성 요소는 서비스를 통해 통신합니다.

이 글을 읽고 나면 아마도 다음과 같은 결과를 얻을 수 있을 것입니다. 프로젝트 구조는 다음과 같습니다. :

@Input 및 @Output 데코레이터를 통해 상위 구성 요소와 하위 구성 요소 간 통신

@Input: 이 속성 바인딩은 상위 구성 요소에서 하위 구성 요소로 데이터를 전송하는 데 사용됩니다. 하위 구성 요소는 다음 두 가지 방법을 통해 속성 변경을 차단할 수 있습니다.

입력 속성 설정자를 사용하여 상위 구성 요소의 값 변경을 차단합니다.

  1. ngOnchanges()를 사용하여 입력 속성 값의 변경 사항을 가로채세요.

  2. @Output: 이 데이터 바인딩은 하위 구성 요소에서 데이터와 이벤트를 상위 구성 요소에 전달하는 데 사용됩니다.

    <!--parent.component.html-->
    <p style="width: 1000px;margin: auto">
    <p class="card" style="width: 500px;float: left">
     <p class="card-header">
      父组件
     </p>
     <p class="card-body">
      <h5 class="card-title">父组件</h5>
      <p class="form-group">
       <label for="input">父组件输入:</label>
       <input type="text"
           class="form-control"
           id="input"
           placeholder="Input something"
           [(ngModel)]="parentPrint" 
       >
       <label for="output">父组件输出:</label>
       <input type="text"
           class="form-control"
           id="output"
           placeholder="Output something"
           [(ngModel)]="contentFromChild"
       >
      </p>
     </p>
    </p>
    <app-child
     [fromParent]="parentPrint"
     (fromChild)="fromChild($event)"
    ></app-child>
    </p>
    로그인 후 복사
    <!--child.component.html-->
    <p class="card" style="width: 500px;">
     <p class="card-header">
      子组件
     </p>
     <p class="card-body">
      <h5 class="card-title">子组件</h5>
      <p class="form-group">
       <label for="input">子组件输入:</label>
       <input type="text"
           class="form-control"
           id="input"
           placeholder="Input something"
           [(ngModel)]="contentFromChild"
       >
       <label for="output">子组件输出:</label>
       <input type="text"
           class="form-control"
           id="output"
           placeholder="Output something"
           [(ngModel)]="fromParent"
       >
      </p>
      <button class="btn btn-primary" (click)="clickChild()">Output方式</button>
     </p>
    </p>
    로그인 후 복사

    효과는 다음과 같습니다: (1. 상위 구성 요소 입력, 하위 구성 요소는 동기적으로 출력할 수 있습니다. 2. 하위 구성 요소 입력에는 (3.) 버튼을 클릭하여 시작 이벤트를 트리거하고 데이터를 상위 구성 요소로 전송합니다.)

@Input : 상위 구성 요소가 입력하는 동안 하위 구성 요소는 표시할 데이터를 동시에 얻을 수 있습니다. 핵심 코드는 다음과 같습니다.

//父组件
parentPrint: any;      //ts中,声明一个变量
[(ngModel)]="parentPrint"  //html中,绑定变量,获取用户输入
//html中,将数据传给子组件
<app-child [fromParent]="parentPrint"></app-child> 
//子组件
@Input() fromParent;    //ts中,用于直接接收从父组件获取的数据
[(ngModel)]="fromParent"  //html中,用于显示数据
로그인 후 복사

setter를 사용하여 입력 속성 값의 변경을 가로채고 하위 구성 요소에 전용 변수를 선언하여 상위 구성 요소가 전달한 데이터를 가져오므로 상위 계층이 하위 계층을 가져오지 못하도록 보호합니다. 정보. (간단한 점은 전달된 데이터를 받기 위해 하위 구성 요소가 무엇을 사용하는지 상위 구성 요소에 알리지 않는다는 것입니다.) 이 방법을 통해서도 동일한 효과를 얻을 수 있습니다.

//子组件
 private _fromParent: any;   //私有变量,通过setter获取父组件的数据
@Input()            //通过setter获取父组件的数据
 set fromParent(fromParent: any) {
  this._fromParent = fromParent;
 }
 get fromParent(): any {
  return this._fromParent;
 }
로그인 후 복사

@Output: 상위 구성 요소가 하위 구성 요소로부터 데이터를 수신하면 하위 구성 요소는 이벤트가 발생하면 하위 구성 요소가 이 속성을 사용하여 이벤트를 내보냅니다(상향 배출). 상위 구성 요소는 이 이벤트 속성에 바인딩되어 이벤트가 발생할 때 응답합니다. 핵심 코드는 다음과 같습니다.

//子组件
@Output() fromChild = new EventEmitter<any>(); //暴露一个输出属性

<button class="btn btn-primary" (click)="clickChild()">Output方式</button> 
 //触发发射函数,将数据发送给父组件
 clickChild() {
  console.log(&#39;click child&#39; , this.contentFromChild);
  this.fromChild.emit(this.contentFromChild);
 }
로그인 후 복사
//父组件
[(ngModel)]="contentFromChild" //绑定输出子组件的数据
//使用子组件,绑定事件属性
<app-child
 [fromParent]="parentPrint"
 (fromChild)="fromChild($event)"
></app-child>
//事件处理函数
 fromChild(event) {
  console.log(event);
  this.contentFromChild = event;
 }
로그인 후 복사

부모 컴포넌트는 @ViewChild()를 호출하여 자식 컴포넌트의 데이터를 얻습니다.

부모 컴포넌트의 클래스가 자식 컴포넌트의 속성과 값을 읽어야 하는 경우 또는 하위 구성 요소의 메서드를 호출하면 하위 구성 요소가 ViewChild로 상위 구성 요소에 주입됩니다. ViewChild는 이름에서 알 수 있듯이 하위 구성 요소의 속성과 메서드를 볼 수 있습니다.

<!--parent.component.html-->
<p style="width: 1000px;margin: auto">
<p class="card" style="width: 500px;float: left">
 <p class="card-header">
  父组件
 </p>
 <p class="card-body">
  <h5 class="card-title">父组件</h5>
  <p class="form-group">
   <label for="viewoutput">ViewChild父组件输出:</label>
   <input type="text"
       class="form-control"
       id="viewoutput"
       placeholder="ViewChild父组件输出"
       [(ngModel)]="viewOutput"
   >
  </p>
  <button class="btn btn-primary" (click)="clickView()">ViewChild方式</button>
 </p>
</p>
<app-child></app-child>
</p>
로그인 후 복사
<!--child.component.html-->
<p class="card" style="width: 500px;">
 <p class="card-header">
  子组件
 </p>
 <p class="card-body">
  <h5 class="card-title">子组件</h5>
  <p class="form-group">
   <label for="input">子组件输入:</label>
   <input type="text"
       class="form-control"
       id="input"
       placeholder="Input something"
       [(ngModel)]="contentFromChild"
   >
  </p>
 </p>
</p>
로그인 후 복사
효과는 다음과 같습니다.

상위 구성 요소 핵심 코드:

//ts
@ViewChild(ChildComponent)         // 使用viewChild导入引用
private childComponent: ChildComponent;   // 将子组件注入到私有属性
//获取子组件数据并显示
clickView() {
  //直接获取子组件的属性
  this.viewOutput = this.childComponent.contentFromChild;
 }
로그인 후 복사
//html
[(ngModel)]="viewOutput"
 <button class="btn btn-primary" (click)="clickView()">ViewChild方式</button>
로그인 후 복사

상위 구성 요소와 하위 구성 요소는 서비스를 통해 통신합니다.

상위 구성 요소와 하위 구성 요소는 동일한 서비스를 공유합니다. 이 서비스를 사용하는 가족은 양방향 통신을 합니다.

<!--parent.component.html-->
<p style="width: 1000px;margin: auto">
<p class="card" style="width: 500px;float: left">
 <p class="card-header">
  父组件
 </p>
 <p class="card-body">
  <h5 class="card-title">父组件</h5>
  <p class="form-group">
   <label for="serviceoutput">父组件服务输入:</label>
   <input type="text"
       class="form-control"
       id="serviceoutput"
       placeholder="服务输入"
       [(ngModel)]="serviceInput"
   >
  </p>
  <button class="btn btn-primary" (click)="clickService()">Service方式</button>
 </p>
</p>
<app-child></app-child>
</p>
로그인 후 복사
<!--child.component.html-->
<p class="card" style="width: 500px;">
 <p class="card-header">
  子组件
 </p>
 <p class="card-body">
  <h5 class="card-title">子组件</h5>
  <p class="form-group">
   <label for="serviceoutput">子组件服务输入:</label>
   <input type="text"
       class="form-control"
       id="serviceoutput"
       placeholder="服务输入"
       [(ngModel)]="serviceInput"
   >
  </p>
  <button class="btn btn-primary" (click)="clickService()">Service方式</button>
 </p>
</p>
로그인 후 복사
//服务
//meditor.service.ts
import {Injectable} from &#39;@angular/core&#39;;
import {Subject} from &#39;rxjs/Subject&#39;;
import {Observable} from &#39;rxjs/Observable&#39;;

@Injectable()
export class MeditorService {
 private subject = new Subject<MeditorMsg>();
 constructor() {}
 // 获取订阅者
 public getObservable(): Observable<MeditorMsg> {
  return this.subject.asObservable();
 }
 // 推送信息
 public push(msg: MeditorMsg) {
  this.subject.next(msg);
 }
}
// 中间者信息
export interface MeditorMsg {
 id: string;
 body: any;
}
로그인 후 복사
효과는 다음과 같습니다.

상위 구성 요소와 하위 구성 요소의 핵심 코드는 생성자에서 서비스 인스턴스 자체에 주입됩니다. 데이터를 푸시하기 위해 상위 컴포넌트 또는 하위 컴포넌트가 push() 메소드를 호출하면 양측 모두 데이터를 수신할 수 있습니다. 이때 ID를 기준으로 상위 컴포넌트 또는 하위 컴포넌트가 데이터를 사용하는지 확인해야 합니다. 핵심 코드는 다음과 같습니다.

subscription: Subscription = null; //初始化一个订阅对象
//子组件构造函数,用于监听数据推送
constructor(
  private meditor: MeditorService
 ) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === &#39;parent&#39;) {   //id为parent,获取父组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 子组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: &#39;parent&#39;, body: this.serviceInput});
 }
//父组件构造函数,用于监听数据推送
constructor(
  private meditor: MeditorService
 ) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === &#39;child&#39;) {    //id为child,获取子组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 父组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: &#39;parent&#39;, body: this.serviceInput});
 }
로그인 후 복사

위에서 작성한 내용은 그다지 완전하지 않습니다. 즉, 수명 주기가 끝나기 전, 즉 onDestroy 주기에서는 구독을 취소해야 합니다.

위는 제가 최근에 사용하고 있는 컴포넌트 인터랙션을 요약한 것입니다. 개인적으로는 서비스를 통한 상호작용이 확장성이 더 높다고 생각합니다. 예를 들어, 우리 프로젝트는 동적으로 표시되는 사이드바를 사용합니다. 사이드바를 클릭하여 다른 시간에 표시하면 다른 내용이 표시됩니다. 이때, 사이드바는 상위 컴포넌트로 사용되며, 하위 컴포넌트는 메시지의 일부로 상위 컴포넌트에 전달되며, 상위 컴포넌트는 하위 컴포넌트 이름을 기반으로 템플릿을 동적으로 생성하여 사이드바에 표시합니다. . 말도 안 되는 이야기를 너무 많이 한 후에 다음 그림은 다음을 의미할 것입니다.

위 내용은 제가 모든 사람을 위해 편집한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.

관련 기사:

PHP 클로저 및 익명 함수(자세한 튜토리얼)

WeChat 애플릿에서 3단계 연결 선택기를 사용하는 방법

jquery를 사용하여 아코디언 효과를 얻는 방법

위 내용은 Angular2에서 부모-자식 구성 요소 통신을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿