2016-02-23 22 views
8

私が見つけたすべてのチュートリアルと回答は、入力を使用して親コンポーネントから子コンポーネントに変数を渡す方法のみを示していますが、この子コンポーネントはルータ内に含まれています親テンプレートの中に直接はありませんか?角2親コンポーネントからルータアウトレットに変数を渡す方法

例:

主成分この例ではそう

@Component({ 
    selector: 'my-app', 
    template: ` 
      Main page 
      <router-outlet></router-outlet> 
       `, 
    directives: [ROUTER_DIRECTIVES] 
}) 

@RouteConfig([ 
    { path: '/contact', name: 'Contact', component: ContactComponent}, 
]) 

export class AppComponent{ 
    public num:Number = 123; 
} 





@Component({ 
    selector: 'contact-page', 
    template: 'contact page' 
}) 
export class ContactComponent{ 
    public num:Number; 
} 

主成分テンプレート子接触コンポーネントがレンダリングされるルータのコンセントが含まれているが、どのように私は、変数を取得することができます「NUM」親コンポーネントのルータ出口で評価された子コンポーネントの値??

+1

も参照してくださいhttp://stackoverflow.com/questions/34363792/angular2-using-inputs-with-router-outlets – Blauhirn

答えて

0

現在、ルータによって追加されたコンポーネントにバインドすることはできません。追加されたコンポーネントとの間でデータをやりとりしたり、イベントを購読したりするには、代わりに共有サービスを使用します(ここではたくさんの例があります)。あなたのデータが不変であるならば、この問題https://github.com/angular/angular/issues/4452特にこのコメントhttps://github.com/angular/angular/issues/4452#issuecomment-153889558

+0

共有サービスは、たとえば、すべてのアプリ設定を取得するサービスがあると思われる場合は理想的ではありませんデータベースからこれらの設定の一部をメインコンポーネントに表示する必要があります。たとえば、ページの上部に電子メールを表示したり、電話番号を表示したりする必要があります。サービスでは、同じページで2回AJAXコールを行い、同じ詳細情報を取得します。私のポイントを見て願っています。 –

+1

実際には、サービスの使用方法と「ajax呼び出しを2回行う」方法は関連していません。 'ParentComponent'(' を含む)と ' 'に追加されたコンポーネントを' ParentComponent'のプロバイダリストに追加するだけでデータを渡すことができます共有サービスは、ajax呼び出しを行うグローバルサービスに依存する可能性があります。たとえば、データがすでに先にフェッチされている場合は、キャッシュされた結果が返されます。 –

+0

私は、親から1回、子から同じ情報を2回取得する必要はなく、結果をキャッシュするというアイデアは、この二重取り出しを防ぐことができますが、私はラップできないという考え方です親コンポーネントの結果をフェッチして、その子に渡すことができれば、私の頭の周りに頭があります。なぜなら、このケースの子がルータのアウトレットに含まれていれば、私は同じことをすることができません。この問題。 –

-1

は、あなたがRouteDataを使用することができます

も参照してください。

@Component({...}) 
@RouteConfig([ 
    { path: '/contact', name: 'Contact', component: ContactComponent, data: {num: 123}}, 
]) 
export class AppComponent { 
} 

@Component({...}) 
export class ContactComponent { 
    public num:Number; 
    constructor(data: RouteData) { 
    this.num = data.get('num'); 
    } 
} 

は、子のルートにハードコードしたくないいくつかの設定オプションを渡すことが有用であろう。しかし、データが変更されることを期待している場合は、別の方法が必要です。

+0

これは、最新のリリースのAngular 2ルータで非推奨になりました。 –

3

私はちょうどこの質問を見つけた、ここで私は同様の問題を解決した方法です。

私はこれを解決するサービスを使用します。そうすれば、すべての子と親がプロパティを設定することができ、変更はすべてのサブスクライバに対して伝播されます。最初に私はReplaySubjectをカプセル化のみ観察可能返すために、公共のgetterとsetterを持つ民間BehaviorSubjectでサービスを作成します。

private _property$: BehaviorSubject<number> = new BehaviorSubject(1); 

set property(value: number) { 
    this._property$.next(value); 
} 

get property$(): Observable<number> { 
    return this._property$.asObservable(); 
} 

新しいBehaviorSubjectを使用する理由を(1)に初期値を設定することです1ので、購読するものがあります。 oninitを両親に

、私は、プロパティの南東デフォルト値(数値)になります。子コンポーネントのの一つ以上で

private _propertySubscribtion: Subscription 

ngOnInit() { 
    // set default value to 5 
    this._componentService.property = 5; 

    // If property is updated outside parent 
    this._componentService.property$.subscribe(p => { 
     this.property = p; 
    }); 
} 

ngOnDestroy() { 
    this._propertySubscribtion.unsubscribe(); 
} 

、変更のために購読することが可能に:

private _propertySubscribtion: Subscription 

ngOnInit() { 
    this._propertySubscribtion = this._componentService.property$.subscribe(p => { 
     this.property = p; 
    }); 
} 

ngOnDestroy() { 
    this._propertySubscribtion.unsubscribe(); 
} 

そして、いくつかの子供や親がプロパティを更新する場合:

updateProperty() { 
    // update property 
    this._componentService.property = 8; 
} 

すべての加入者はそれについて知っているだろう。

+0

プロパティを更新せずに最初のエミション後にプロパティ値を削除する方法はありますか? – PaladiN

+0

値をnullに設定するだけで十分でしょうか。私は、HTTPリクエストが終了する前に、初期値としてnull値を使用することがあります。 – DNRN

+0

うん。また、最初にnullに設定してから、操作後に値を再びnullに設定しました。ありがとうございました... – PaladiN