2016-11-03 1 views
4

각도 2.0.1을 사용하고 있습니다.@ContentChild의 각도 2 참조 동적 인스턴스

<ng-content>을 통해 다른 구성 요소를 사용할 수있는 구성 요소가 있습니다.

주입 된 구성 요소를 참조하고 싶습니다. 내가 <ng-content>은 지금까지 내가 말할 수있는 하나 개의 요소가 될 것이라는 점을 알았다면

: @ContentChild(MyComponent) dynamicTarget: IMyComponent;를하지만 어떤 구성 요소가 될 수 있기 때문에 (내가 만드는 것이 유일한 가정은 어떤 주입 구성 요소가 특정 인터페이스를 구현된다)가 까다 될 .

또한 <ng-content #dynamicTarget'>을 시도한 다음 @ContentChild('dynamicTarget') dynamicTarget: IMyComponent;이라고 말하면이 값은 정의되지 않은 값을 나타냅니다.

누구나 내가이 기능이 컴포넌트의 인스턴스이므로 Angular 2에 어떻게 함수를 호출 할 수 있는지 알 수 있습니까?

유스 케이스를 더욱 명확히하기 위해 콘텐츠로 모든 구성 요소를 수용 할 수있는 다중 단계 마법사가 있으며 내용에 validate 함수를 호출하려고합니다 (다시 말하면,)

+1

"문제를 해결하는 가장 좋은 방법은 더 이상 가지고 있지 않은지 확인하는 것입니다." 단계가 구성 요소로 정의 된 경우 transclusion (NgContent)을 사용하는 대신 마법사에서 수동으로 만들 수 있으며 구성으로 전달할 수 있습니다. 예를 들어,이 Plunker (http://plnkr.co/edit/6I5e53fOzu9ywS3FzHlc)를 확인하십시오. –

+0

@ S.Klechkovski 필자의 첫 번째 프로토 타입은 실제로이 구성 요소와 같은 구성 요소의 배열을 실제로 사용했기 때문에 작동 시켰습니다. 대신'ng-content '로 할 수 있다면 정말 더 궁금합니다. (다른 이유로 HTML에서 구성 마법사를 빌드하는 것보다 config 객체). config 객체로 돌아갈 가능성이 없다고 생각합니다. – Johannes

답변

3

하나의 접근법은 어떤 동적 구성 요소에도 동일한 #id을 부여하는 것일 수 있습니다. 나는 #thoseThings을 받았습니다. (나는 거의 @Missingmanual과 같다고 생각한다.)

PLUNKER (일치하는 부분을 보려면 콘솔을 참조하십시오.)

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div [style.border]="'4px solid red'"> 
    I'm (g)Root. 

    <child-cmp> 
     <another-cmp #thoseThings></another-cmp> 
    </child-cmp> 
    </div> 
    `, 
}) 
export class App { 
} 


@Component({ 
    selector: 'child-cmp', 
    template: ` 
    <div [style.border]="'4px solid black'"> 
     I'm Child. 
     <ng-content></ng-content> 
    </div> 
    `, 
}) 
export class ChildCmp { 
    @ContentChildren('thoseThings') thoseThings; 

    ngAfterContentInit() { 
    console.log(this.thoseThings); 

    this.validateAll(); 

    if(this.thoseThings){ 
    this.thoseThings.changes.subscribe(() => { 
     console.log('new', this.thoseThings); 
    }) 
    } 
    } 

    validateAll() { 
    this.thoseThings.forEach((dynCmp: any) => { 
     if(dynCmp.validate) 
     dynCmp.validate(); // if your component has a validate function it will be called 
    }); 
    } 
} 


@Component({ 
    selector: 'another-cmp', 
    template: ` 
    <div [style.border]="'4px solid green'"> 
     I'm a Stranger, catch me if you can. 
    </div> 
    `, 
}) 
export class AnOtherCmp { 
} 
+0

이것은 실제로 정말 멋지다. ID를 외부에 던지는 것을 고려하지 않았다. (나는 작동하지 않는 ng-content 자체에 관한 것이었다.) 그것은 구현 자의 ID를 던져야 할 필요가 있다는 점에서 이상적인 것보다 약간 적습니다. 그러나 이것은 페이지의 여러 구성 요소를 허용하고 더 읽기 쉽기 때문에 구성 방법보다 낫습니다. 지금까지 이것이 최선의 선택입니다. 고맙습니다. – Johannes

+1

나는 이것을 내 코드에서 구현할 수 있었고 실제로이 결과를 좋아한다. 그래서 이것을 받아 들여 현상금을 수여 할 것이다. Ankit에게 다시 한 번 감사드립니다. – Johannes

+0

정말 도움이 되서 다행입니다. 감사합니다. 감사합니다;) –

1
NgModule와 함께 작동하도록 할 수 없습니다3210
@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App, Parent, Transcluded1, Transcluded2 ], 
    providers: [ 
    {provide: TranscludedBase, useExisting: Transcluded1, multi:true} 
    {provide: TranscludedBase, useExisting: Transcluded2, multi:true} 
    ], 
    bootstrap: [ App ] 
}) 

Plunker example

Plunker example

+0

[Issue # 8580] (https://github.com/angular/angular/issues/8580) 매우 유사하며 지원되는 것으로 보입니다. 유일한 차이점은 동적 구성 요소와 하드 코딩 된 구성 요소를 사용하고 있다는 것입니다. Angular가 문제에 대해 좀 더 나은 통찰력을 얻기 위해 문제를 제기했습니다. – Johannes

+0

또한 두 번째 예제의 절충을 좋아하지만 구성 요소 배열이 필요합니다. 모든 구성 요소를 두 번 정의하면 유지 관리가 쉽지 않습니다.하지만 예제와 대안 솔루션을 고맙게 생각합니다. – Johannes

+0

이것들이 단지 workaround 일 뿐인 것에 동의합니다. –

-1

당신이 알고있는 경우 모든 당신의 구성 요소는 validate이고 동일한 인터페이스를 구현합니다. IValidate, 당신은이 요청 된 인터페이스에 맞는로

@ContentChild('IValidate') dynamicTarget: IValidate; 
// ... 
this.dynamicTarget.validate(); 

각도만큼 정확한 클래스에 대해 상관하지 않는다 말할 수 있습니다.

+1

이것이 효과가 있다면 좋을 것입니다. 하지만 인터페이스와 추상 클래스 모두에서이 기술로 성공하지 못했습니다. 이 작업을 수행 할 수 있다면 (plunkr을 사용하여) 최선의 답을 기꺼이 받아 들여야합니다. – Johannes