>  기사  >  웹 프론트엔드  >  Angular2 상위-하위 컴포넌트 통신 방법

Angular2 상위-하위 컴포넌트 통신 방법

php中世界最好的语言
php中世界最好的语言원래의
2018-03-23 09:36:561832검색

이번에는 Angular2 부모-자식 컴포넌트 통신 방법을 알려드리겠습니다. Angular2 부모-자식 컴포넌트 통신 방법을 사용할 때 주의 사항은 무엇입니까?

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

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

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

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

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

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

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

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

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

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

  2. @Output:

    데이터 바인딩

    은 하위 구성 요소에서 데이터와 이벤트를 상위 구성 요소에 전달하는 데 사용됩니다.
  3. <!--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('click child' , 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 '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';
@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;
}
효과는 다음과 같습니다.

상위 구성 요소와 하위 구성 요소의 핵심 코드는

constructor

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

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

我上面写的还不是很完善,就是在生命周期结束前,也就是在onDestroy周期中,要取消订阅。

以上,就是最近在使用的组件交互的总结。个人觉得通过服务来交互的可扩展性更强。例如,我们项目中用到了一个动态显示的侧栏,不同时期点击显示侧栏要显示不同的东西。这个时候把侧栏作为父组件,子组件作为消息的一部分传递给父组件,父组件根据子组件名动态生成模板,显示在侧栏上面。说了这么多废话大概就是下图的意思:

最后附上demo源码:父子组件交互demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

jQuery代码优化方式的总结

360浏览器兼容模式的页面显示不全怎么处理

위 내용은 Angular2 상위-하위 컴포넌트 통신 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.