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,
....
