如何为SharedService类设置全局变量?
首先要明确:在Angular中,如果你的SharedService是根注入的单例服务(通常通过providedIn: 'root'配置),那么服务里的属性本身就是全局可共享的状态——因为整个应用只会有一个服务实例,所有组件注入它都会拿到同一个对象。你的代码里主要有两个问题需要修正,才能正确维护和访问这些全局变量:
1. 先修正回调函数的this指向问题
你的save插件的callback里,this默认指向的是Darkroom的save插件实例,而不是SharedService的实例,所以直接用this.isDarkroom根本不会修改服务里的变量。解决这个有两种常用方法:
方法A:使用箭头函数(推荐)
箭头函数会继承外层上下文的this,也就是SharedService实例:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class SharedService { isDarkroom = false; imageCroppedBase64: string | null = null; // 提前声明变量并指定类型 darkroom: Darkroom | null = null; // 提前声明Darkroom实例变量 createDarkromInstance(width, height) { this.darkroom = new Darkroom("#img", { // Size options minWidth: 300, minHeight: 300, maxWidth: 900, maxHeight: 900, ratio: width/height, backgroundColor: "#fff", plugins: { crop: { minHeight: 50, minWidth: 50 }, save: { // 换成箭头函数,this将指向SharedService实例 callback: () => { this.darkroom?.selfDestroy(); this.imageCroppedBase64 = this.darkroom?.canvas.toDataURL() || null; this.isDarkroom = true; } }, brush: false }, initialize: function() { // 你的初始化逻辑 } }); } }
方法B:提前保存this的引用
如果因为某些原因不能用箭头函数,可以在外层把this存成一个变量(比如self):
createDarkromInstance(width, height) { const self = this; // 保存SharedService实例的引用 this.darkroom = new Darkroom("#img", { // ... 其他配置不变 plugins: { save: { callback: function() { self.darkroom?.selfDestroy(); self.imageCroppedBase64 = self.darkroom?.canvas.toDataURL() || null; self.isDarkroom = true; } }, }, }); }
2. 确保服务是全局单例
要让这些变量真正全局可用,必须保证SharedService是应用级的单例。在Angular中,最简单的方式是在服务的@Injectable装饰器里配置providedIn: 'root'(如上面代码所示)。这样不管哪个组件注入SharedService,拿到的都是同一个实例,修改isDarkroom或者imageCroppedBase64后,所有注入该服务的地方都能看到最新值。
3. 进阶:用Observable实现响应式全局状态
如果希望组件能自动监听这些变量的变化,可以把变量改成BehaviorSubject(RxJS提供的类),这样组件可以订阅状态变化,无需手动轮询:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SharedService { // 用BehaviorSubject存储私有状态,初始值为false private isDarkroomSubject = new BehaviorSubject<boolean>(false); // 对外暴露只读的Observable,供组件订阅 isDarkroom$ = this.isDarkroomSubject.asObservable(); private imageCroppedSubject = new BehaviorSubject<string | null>(null); imageCroppedBase64$ = this.imageCroppedSubject.asObservable(); darkroom: Darkroom | null = null; createDarkromInstance(width, height) { this.darkroom = new Darkroom("#img", { // ... 其他配置 plugins: { save: { callback: () => { this.darkroom?.selfDestroy(); const base64 = this.darkroom?.canvas.toDataURL() || null; this.imageCroppedSubject.next(base64); // 更新图片状态 this.isDarkroomSubject.next(true); // 更新darkroom状态 } }, }, }); } // 提供手动修改状态的方法,方便其他组件调用 setIsDarkroom(value: boolean) { this.isDarkroomSubject.next(value); } }
然后在组件里订阅状态变化:
import { Component, OnInit } from '@angular/core'; import { SharedService } from './shared.service'; @Component({ selector: 'app-example', template: `<p>Darkroom状态:{{ isDarkroom }}</p>` }) export class ExampleComponent implements OnInit { isDarkroom = false; constructor(private sharedService: SharedService) {} ngOnInit() { // 订阅状态变化,自动更新组件内的变量 this.sharedService.isDarkroom$.subscribe(value => { this.isDarkroom = value; }); } }
内容的提问来源于stack exchange,提问作者Walter White
相关产品推荐
相关产品推荐

