2017-11-26 1 views
0

これは、角度2+の質問であり、コンセプトのクロスコンポーネントアクセス(私が作成したばかりです)と、それが達成可能かどうかです。ここでcomponentYにいるときにcomponentXのHTMLコンテンツとTSメソッドを活用して使用する方法は?

はシナリオです:

私は私が#sidenav

<button type="button" mat-icon-button  (click)="sidenav.toggle()"> 
    <mat-icon> 
     search 
    </mat-icon> 
</button> 

を切り替えることができます。このボタンを得た後、私は上記のボタンがクリックされたときに現れる対応#sidenavコンテンツを得ました。

<mat-sidenav #sidenav > 

    HTML to go here... 

</mat-sidenav> 

これは機能しています。ボタンをクリックするたびに、ここでHTMLのテキストをオン/オフするセクションが表示されます。

しかし、ここで私が満足したいと思う非常に挑戦的な希望です。

私は、そこにいくつかのヴァースとメソッドを持つ別のコンポーネントがあります。 電話番号XComponent

XComponent.tsにはこれらがあります。ここでは、この

<div id="take-me-and-show-my-contents-in-the-sidenav-when-button-is-clicked"> 
    <button (click)='alertX()'></button> 
</div> 

を持っている

x=10; 

alertX(){ 
    alert(this.X); 
} 

XComponent.htmlは挑戦的な質問です。

上記のid(take-me-and-show ...)でdivを取得し、内容を他のコンポーネントの#sidenavコンテンツエリアにプログラムで表示できますか?したがって、HTML to go here<button (click)='alertX()'></button>

と置き換えられます。可能であれば、XコンポーネントのalertXを呼び出すボタン(クリック)イベントは、最初のコンポーネントで実行しても引き続き動作しますか?

このようなクロスコンポーネントアクセスは不可能ですか?最高の基準はまだ英雄の見学されたコンポーネントの通信のため

+0

divはXComponent.htmlの全範囲ですか?もしそうなら、私は[動的コンポーネント](https://angular.io/guide/dynamic-component-loader)があなたが望む意図を持っていると推測しています。 clickイベントに関しては、XComponentはそのイベントを親に送信する必要があります。 –

+0

Richardに感謝します。しかし、XComponentにはdivがいくつかあるので、あなたの質問に答えてください。いいえ、HTML全体ではありません。 –

+0

私は、次の夢を実現する機能をほとんど探しています。(click)= 'XComponent.ts-> alertX()'これにより、alertX()がどこにあるのかを角度で確認できます。もう1つは{{XComponent.html-> ThatDiv}}です。 :) –

答えて

0

parent=>child(@Input()および値のストリームまたは直接値のいずれかを使用して - 後者のハンドルがChangeDetection自動的値の変化に)

child=>parent(@output()と持つEventEmitterを使用していますが、件名またはBehaviorSubject同様に、他の観察を使用することができる)(ストリームエンティティを含むよう注射サービスを使用して)

distant relatives or siblings

1

例のコードは間違いありません。

私の最初のアイデアは、XComponentにViewChildの形式でいくつかの配管を追加することです。これにより、XComponentが使用されているコンテキストに応じてさまざまなdivをオンまたはオフできます。

私は、標準的なAngularな使い方、つまりViewChildとngIfの範囲内でコードを保持しようとしています(つまり、DOM操作を使わない、つまり[hidden]でさえ)。

はここで動的サイド-NAVテンプレートにthis.xcomponent.takeMeを追加するかもしれませんしようとするPlunker

@Component({ 
    selector: 'x-component', 
    template: ` 
    <div #takeme> 
    <button (click)='alertX()'></button> 
    </div> 
    <div #another1 *ngIf="showAll"> 
    Hello x-component 
    </div> 
    <div #another2 *ngIf="showAll"> 
    Hello again x-component 
    </div> 
`, 
}) 
export class XComponent { 
    @ViewChild('takeme') takeMe: ElementRef; 
    @ViewChild('another1') another1: ElementRef; 
    @ViewChild('another2') another2: ElementRef; 
    name:string; 
    @Input() showAll = true; 

    alertX() { 
    console.log('alertX()') 
    } 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 

     <br/><hr/> 
     I'm a 'normal' usage of XComponent 
     <x-component></x-component> 

     <br/><hr/> 
     Pretend I'm a side-nav 
     <x-component [showAll]="false" #xcomponent></x-component> 
    </div> 
    `, 
}) 
export class App { 
    @ViewChild('xcomponent') xcomponent: ElementRef; 
    name:string; 
    constructor() { 
    console.clear() 
    this.name = `Angular! v${VERSION.full}` 
    } 

    ngAfterViewInit() { 
    this.xcomponent.alertX = this.myAlertX 
    } 

    myAlertX() { 
    console.log('parent alertX') 
    } 
} 


次のことです。 Renderer2

を使用して


ここで少しXComponentの侵襲である角度のRenderer2を使用したバージョンです。

は、ここでは、DOMが表示されません<template>タグ、内XComponentのインスタンスを作成し、基本的にPlunker

@Component({ 
    selector: 'x-component', 
    template: ` 
    <div #takeme> 
    <button (click)='alertX()'></button> 
    </div> 
    <div #another1> 
    Hello x-component 
    </div> 
    <div #another2> 
    Hello again x-component 
    </div> 
`, 
}) 
export class XComponent { 
    @ViewChild('takeme') takeMe: ElementRef; 

    alertX() { 
    console.log('alertX()') 
    } 
} 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>Hello {{name}}</h2> 

     <br/><hr/> 
     I'm a 'normal' usage of XComponent 
     <x-component></x-component> 

     <br/><hr/> 
     Pretend I'm a side-nav 
     <div #takemediv></div> 
     <template> 
     <x-component #xcomponent></x-component> 
     </template> 
    </div> 
    `, 
}) 
export class App { 

    @ViewChild('xcomponent') xcomponent: ElementRef; 
    @ViewChild('takemediv') divHost; 

    name:string; 
    constructor(private renderer: Renderer2) { 
    console.clear() 
    this.name = `Angular! v${VERSION.full}` 
    } 

    ngAfterViewInit() { 
    this.renderer.setProperty(this.divHost.nativeElement, 'innerHTML', 
     this.xcomponent.takeMe.nativeElement.innerHTML); 
    const button = this.divHost.nativeElement.querySelector('button'); 
    this.renderer.listen(button, 'click',() => this.myAlertX()) 
    } 

    myAlertX() { 
    console.log('parent alertX') 
    } 
} 

です。

次に、私たちが必要とするdivをRenderer2を使用してホストdivに配置し、同じツールでclickイベントをフックアップします。

最初のバージョンを上回る利点は、表示したくないdivの* ngIf属性を不要にすることです(特定のdivを抽出するのでになります)。

+0

私はこのリチャードをテストするつもりです。これについて考えていただきありがとうございます。感謝。 –

+0

乾杯。 XComponentへの影響が少ないバージョンで作業しています。 –

関連する問題