ค้นหาเว็บไซต์

การฉีดพึ่งพา - การเข้าถึงข้อมูล/คุณสมบัติของคอมโพเนนต์พ่อจากคอมโพเนนต์ลูกใน Angular2


ฉันถึงขีดสุดของความกลุ้มใจและไม่รู้จะทำอย่างไรแล้ว ใกล้จะร้องไห้เต็มที!

ฉันกำลังพยายามสอนตัวเอง Angular2 หลังจากหลายปีที่มีความสุขกับการใช้ AngularJS - ฉันมีแอป Angular2 ที่มีคอมโพเนนต์ระดับบนแบบเรียกว่า App

@Component({
    selector: 'app', // <app></app>
    providers: [...FORM_PROVIDERS],
    directives: [...ROUTER_DIRECTIVES],
    template: require('./app.html')
})

@RouteConfig([
    {path: '/', component: Home, name: 'Home'},
    {path: 'about', component: About, name: 'About'},
    {path: 'profile', component: Profile, name: 'Profile'},
    {path: 'profile/:id', component: ForeignProfile, name: 'ForeignProfile'}
])

export class App {
    userStatus: UserStatus;
    userOnlineContacts: UserContact[];

    constructor(private userData: UserData) {
        this.userStatus = new UserStatus();
    }

    ngOnInit() {
         Observable.forkJoin([
            this.userData.getUserStatus(),
            this.userData.getContacts()
         ]).subscribe( (t) => {
                this.userStatus = t[0];
                this.userOnlineContacts = t[1].onlineContacts;
         });

        // Polling thing for this.userOnlineContacts...
        this.userData.pollContacts().subscribe(
            (data) => {
                this.userOnlineContacts = data.onlineContacts;
            });
    }
}

ฉันดูเหมือนแบบนี้ในไฟล์ index.html ของฉัน

<app>Loading...</app>

ตอนนี้ฉันกำลังใช้ ng-router ดังนั้นภายใน app.html ของฉันฉันมีแท็ก <router-outlet></router-outlet> ที่ซ้อนอยู่ใน HTML ของฉัน ดังนั้นคอมโพเนนต์ลูกของฉันจะถูกฉีดเข้าไปในแท็กเหล่านี้ - ฉันไม่เคยวางแท็ก selector ของฉันลงใน HTML (ดังนั้นฉันคิดว่าฉันไม่สามารถส่งข้อมูลโดยใช้การผูกข้อมูลได้) ภายใน <router-outlet></router-outlet> ฉันเข้าถึงคอมโพเนนต์ลูกเมื่อฉันไปยังคอมโพเนนต์ ForeignProfile โค้ดของคอมโพเนนต์ลูกมีดังนี้...

@Component({
    selector: 'foreign-profile',
    template: require('app/components/foreign-profile/foreign-profile.html'),
    providers: [],
    directives: [],
    pipes: []
})

export class ForeignProfile implements OnInit {

    userProfile: any;
    routeId: string;
    userPhotos: any;
    userInfo: any;

    constructor(private userData: UserData, private routeParams: RouteParams) {
        this.routeId = routeParams.get('id');
        this.userProfile = {}; // not sure why I need to put this here otherwise we have 'undefined' error
    }

    ngOnInit() {
        // Use forkJoin as we don't need order in the calls
        Observable.forkJoin([
            this.userData.getUserPhotos(this.routeId),
            this.userData.getUserInfo(this.routeId),
            this.userData.getUserBaseData(this.routeId)])
            .subscribe(t => {
                this.userPhotos = t[0];
                this.userInfo = t[1];
                this.userProfile = t[2];
                // do more stuff here

        });
    }
}

ภายในคอมโพเนนต์นี้ ฉันต้องการเข้าถึงคุณสมบัติของคอมโพเนนต์ App เช่น this.userStatus และ this.userOnlineContacts ฉันไม่ต้องการสร้างเซอร์วิสเพื่อทำการเรียก HTTP ซ้ำ ๆ ฉันต้องการฉีดคุณสมบัติของพ่อแม่โดยตรงไปยังลูก ใน AngularJS ฉันสามารถใช้สิ่งเช่น $scope.$parent.userStatus ตอนนี้ฉันได้ลองดูการฉีดพ่อแม่ (App) เข้าสู่ลูก (ForeignProfile) โดยการแก้ไขคอมโพเนนต์:

นี่คือคอมโพเนนต์ ForeignProfile

import {App} from '../../app'

@Component({
    // blah blah...
})

export class ForeignProfile implements OnInit {

    // code removed for example, easier to read
    userStatus: any;

    constructor(private userData: UserData, private routeParams: RouteParams, @Inject app:App) {
        // code removed for example, easier to read
        this.userStatus = app.userStatus;
    }

และจากนั้นกับผู้ปกครอง...

import {Injectable, Component} from 'angular2/core';

@Injectable()
@Component({
    selector: 'app', // <app></app>

นี่ทำให้คอนโซลของฉันบ้าไปเลย ใครสามารถอธิบายได้บ้างว่าฉันสามารถเข้าถึงคุณสมบัติจากคอมโพเนนต์ App ในคอมโพเนนต์ ForeignProfile ของฉันได้อย่างไร? ฉันเสียเวลามาหลายชั่วโมงแล้ว ขอบคุณล่วงหน้านะ

คำตอบ #1

ตามที่ @ Günter Zöchbauer ระบุไว้อย่างถูกต้อง คุณต้องใช้แนวคิดการบริการของ Angular เพื่อแบ่งปันข้อมูลระหว่างส่วนประกอบ

ในกรณีที่คุณยังต้องการเข้าถึงส่วนประกอบ App ของคุณ คุณสามารถทำได้ในตัวสร้าง ForeignProfile แบบนี้:

constructor(@Host() @Inject(forwardRef(() => App)) app: App)
{

}