2016-06-07 1 views
34

각도가있는 문서에는 부모로부터의 아동 사건을 청취하는 주제가 있습니다. 괜찮아. 하지만 내 목적은 그 반대입니다!. 내 애플 리케이션에는 관리자 페이지 (사이드 바 메뉴, 작업 표시 줄, 상태 등 ..)의 레이아웃보기를 보유하고있는 'admin.component'가 있습니다. 이 상위 구성 요소에서 다른 관리자 페이지 간 기본보기를 변경하기 위해 라우터 시스템을 구성했습니다. 문제는 변경 후 항목을 저장하는 것입니다. 사용자가 작업 표시 줄 (admin.component에 있음)의 저장 버튼을 클릭하고 하위 구성 요소가 저장 직원을 수행하기 위해 해당 클릭 이벤트를 청취해야합니다.어린이가 각도 2의 부모 이벤트를 청취합니다.

+2

이 작업을 수행하는 가장 좋은 방법은 서비스를 사용하고 이벤트를 파견하는 것입니다. – zpul

+0

귀하의 질문에이 너무 유사하지 않습니다 : http://stackoverflow.com/questions/35560860/in-angular2-how-to-let-child-components-communicate-with-each-other – freethebees

+0

@freethebees 어쩌면 솔루션은 동일하지만 문제의 모양이 다르므로이 상황에 가장 적합한 방법을 찾는 것이 나의 의도입니다. –

답변

52

나는이 문서가 당신에게 도움이 될 수 있다고 생각 :

는 사실은 부모가 자식에 제공하는 AN/관찰 대상을 활용할 수 있습니다. 뭐 그런 :

@Component({ 
    (...) 
    template: ` 
    <child [parentSubject]="parentSubject"></child> 
    `, 
    directives: [ ChildComponent ] 
}) 
export class ParentComponent { 
    parentSubject:Subject<any> = new Subject(); 

    notifyChildren() { 
    this.parentSubject.next('some value'); 
    } 
} 

구성 요소가 단순히이 주제에 가입 할 수 있습니다 아이 : 그렇지 않으면

@Component({ 
    (...) 
}) 
export class ChildComponent { 
    @Input() 
    parentSubject:Subject<any>; 

    ngOnInit() { 
    this.parentSubject.subscribe(event => { 
     // called when the notifyChildren method is 
     // called in the parent component 
    }); 
    } 

    ngOnDestroy() { 
    // needed if child gets re-created (eg on some model changes) 
    // note that subsequent subscriptions on the same subject will fail 
    // so the parent has to re-create parentSubject on changes 
    this.parentSubject.unsubscribe(); 
    } 

} 

, 당신은 유사한 방법으로 같은 주제를 포함하는 공유 서비스를 활용할 수 ...

+0

상위 구성 요소가 ngInit 내에서 다음 값을 브로드 캐스팅하지 않으면 내 하위 구성 요소의 콜백이 실행되지 않습니다. 왜 그런 경우입니까? – cjsimon

+2

ViewChild보다이 방법을 사용하면 어떤 이점이 있습니까? – sunnyiitkgp

+0

더 전문적으로 보였지만 내 상황에서 실험하기 위해 몇 시간을 준 후 하위 요소를 추가/제거 할 때 UnsubscribeErrors 문제가 발생하지 않아서 주제에서 탈퇴 할 수 없었습니다. 그래서 TimeBoxing을 통해 @StephenPaul에 대한 훨씬 더 직접적인 대답을했습니다. 어쨌든 대답을 주셔서 감사 드리며 아마 rxjs 라이브러리를 충분히 이해하지 못했을 것입니다. 그리고 완벽하게 이해하고 올바른 (여분의) 조정을하여 완벽하게 작동하도록하십시오. –

52

후손을 위해서에 대한보다 일반적인 해결책을 이라고 말하고 싶습니다. 간단히 ViewChild에 대한 참조를 가져 와서 직접 메서드를 호출하십시오.

@Component({ 
    selector: 'app-child' 
}) 
export class ChildComponent { 

    notifyMe() { 
    console.log('Event Fired'); 
    } 
} 

@Component({ 
    selector: 'app-parent', 
    template: `<app-child #child></app-child>` 
}) 
export class ParentComponent { 

    @ViewChild('child') 
    private child: ChildComponent; 

    ngOnInit() { 
    this.child.notifyMe(); 
    } 
} 
+27

답안에서 두 가지를 배웠습니다 - 하위 구성 요소에 대한 참조를 얻는 방법과 후손 * –

+1

의 의미를 얻는 방법 부모 구성 요소를 입력하자마자 충돌 ... ''notifyMe '속성을 읽을 수 없습니다. 정의되지 않음. –

+0

흠, 자녀의 구성 요소가 각도로 설정되지 않은 것 같습니다. ChildComponent에 올바른 셀렉터가 있는지 확인하십시오. –

1

질문을 올바르게 이해하면 더 많은 뼈의 접근이 가능할 수도 있습니다. 가정 - A는 상위 구성 요소에

  • 아이 컴퍼넌트에 저장해야하는 데이터입니다 저장 버튼을 한

    • 영업 이익은
    • 다른 모든 데이터
    • 가해야 할 수도 있습니다 하위 구성 요소 서비스에서 액세스 할 수 있음 상위 구성 요소

      <button type="button" (click)="prop1=!prop1">Save Button</button> 
      <app-child-component [setProp]='prop1'></app-child-component> 
      

      에서 그리고 아이

  • ..

    prop1:boolean; 
        @Input() 
        set setProp(p: boolean) { 
        // -- perform save function here 
    } 
    

    이것은 단순히 버튼 클릭을 하위 구성 요소로 보냅니다. 거기에서 자식 구성 요소는 데이터를 독립적으로 저장할 수 있습니다.

    EDIT : 부모 템플릿의 데이터도 버튼 클릭과 함께 전달해야하는 경우이 방법으로도 가능합니다. 이 경우 알려 주시면 코드 샘플을 업데이트하겠습니다.