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

TypeScript - Angular2 - การแชร์ข้อมูลระหว่างคอมโพเนนต์โดยใช้บริการ


ฉันมีวัตถุหนึ่งที่ฉันต้องการจะแบ่งปันระหว่างคอมโพเนนต์ของฉันในแอป Angular2

นี่คือต้นกำเนิดของส่วนประกอบแรก:

/* app.component.ts */

// ...imports
import {ConfigService} from './config.service';

@Component({
    selector: 'my-app',
    templateUrl: 'app/templates/app.html',
    directives: [Grid],
    providers: [ConfigService]
})
export class AppComponent {
    public size: number;
    public square: number;

    constructor(_configService: ConfigService) {
        this.size = 16;
        this.square = Math.sqrt(this.size);

        // Here I call the service to put my data
        _configService.setOption('size', this.size);
        _configService.setOption('square', this.square);
    }
}

และส่วนประกอบที่สอง:

/* grid.component.ts */

// ...imports
import {ConfigService} from './config.service';

@Component({
    selector: 'grid',
    templateUrl: 'app/templates/grid.html',
    providers: [ConfigService]
})
export class Grid {
    public config;
    public header = [];

    constructor(_configService: ConfigService) {
        // issue is here, the _configService.getConfig() get an empty object 
        // but I had filled it just before
        this.config = _configService.getConfig();
    }
  }

และสุดท้ายคือบริการเล็กๆ ของฉัน คือ ConfigService:

/* config.service.ts */

import {Injectable} from 'angular2/core';

@Injectable()
export class ConfigService {

    private config = {};

    setOption(option, value) {
        this.config[option] = value;
    }

    getConfig() {
        return this.config;
    }
}

ข้อมูลของฉันไม่ได้ถูกแชร์ ในไฟล์ grid.component.ts บรรทัด _configService.getConfig() คืนค่าเป็นวัตถุว่าง แต่ค่าถูกเติมเต็มก่อนหน้านี้ในไฟล์ app.component.ts

ฉันอ่านเอกสารและบทเรียนแล้ว แต่ไม่มีอะไรได้ผล

ฉันกำลังพลาดอะไรอยู่?

ขอบคุณ

แก้ไขแล้ว

ปัญหาของฉันคือฉันกำลังฉีด ConfigService ของฉันสองครั้ง ในการเริ่มต้นใช้งานของแอปพลิเคชันและในไฟล์ที่ฉันกำลังใช้งานมัน

ฉันลบการตั้งค่า providers ออกแล้วและมันทำงานได้!

คำตอบ #1

คุณกำหนดมันภายในสองคอมโพเนนต์ของคุณ ดังนั้นบริการจึงไม่ได้ถูกแชร์ คุณมีอินสแตนซ์หนึ่งสำหรับคอมโพเนนต์ AppComponent และอีกอินสแตนซ์หนึ่งสำหรับคอมโพเนนต์ Grid

@Component({
  selector: 'my-app',
  templateUrl: 'app/templates/app.html',
  directives: [Grid],
  providers: [ConfigService]
})
export class AppComponent {
  (...)
}

วิธีแก้ปัญหาอย่างรวดเร็วคือการลบแอตทริบิวต์ providers ของคอมโพเนนต์ Grid ของคุณ... ด้วยวิธีนี้ อินสแตนซ์ของเซอร์วิสจะถูกแชร์โดย AppComponent และคอมโพเนนต์ลูกของมัน

วิธีแก้อีกวิธีหนึ่งคือการลงทะเบียนผู้ให้บริการที่เกี่ยวข้องภายในฟังก์ชัน bootstrap ในกรณีนี้ อินสแตนซ์จะถูกแชร์โดยทั้งแอปพลิเคชัน

bootstrap(AppComponent, [ ConfigService ]);

ในการเข้าใจว่าทำไมคุณจึงต้องทำเช่นนั้น คุณจำเป็นต้องรับรู้ถึงคุณสมบัติ "hierarchical injectors" ของ Angular2 ลิงก์ต่อไปนี้อาจมีประโยชน์:

  • วิธีที่ดีที่สุดในการฉีดบริการหนึ่งเข้าไปในบริการอื่นใน Angular 2 (Beta) คืออะไร?
  • https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

คำตอบ #2

สำหรับเวอร์ชันล่าสุดของ Angular หากคุณต้องการแชร์บริการ คุณไม่สามารถเพิ่มมันลงในฟังก์ชัน bootstrap ได้ ให้เพิ่มมันในรายการ providers ของ NgModule เหมือนกับที่คุณทำกับบริการปกติ พฤติกรรมเริ่มต้นของมันจะเป็นแบบ singleton

bootstrap(AppComponent);

@NgModule({
    declarations: [
        ....
    ],
    imports: [
       ....     
    ],
    providers: [
        ConfigService,
....

บทความที่เกี่ยวข้อง