网站搜索

typescript - 我如何在我的 Angular 2 应用模块和装饰器之间共享服务实例?


据我理解 Angular 2 服务,如果你在根组件中注入一个服务,所有子组件将共享该服务的同一个实例。

我有一个日志记录服务,我想在我的装饰器和应用程序中使用它。但我想重用来自根组件的现有服务实例。

现在,如果我在日志服务的构造函数中放置一个调试器语句,我的服务会被实例化多次。我正在使用ReflectiveInjector,但我认为它创建了一个新实例,而不是使用全局的那个。

也许我做法错了,或者我缺乏理解。我这么做的原因是因为我在日志服务中有一个可观察的流,并且多个实例会创建多个可观察对象。

@Injectable()
export class LoggerService {

    private _applicationLog$: ReplaySubject<string>;
    get applicationLog$(): Observable<string> {
        return this._applicationLog$.asObservable();
    }

    constructor(private $localStorage: LocalStorageService, private $appSettings: AppSettings) {
        this._applicationLog$ = <ReplaySubject<string>>new ReplaySubject();
    }

    log(s: string){
       //log to a file and push into the stream
       this._applicationLog$.next(s);
    }
}

现在这是我的日志装饰器

var injector = ReflectiveInjector.resolveAndCreate([LocalStorageService, AppSettings]);
var service = <LoggerService>injector.resolveAndInstantiate(LoggerService);
var appSettings = <AppSettings>injector.resolveAndInstantiate(AppSettings);

function getTime() {
    let now = new Date();
    let min = ("00" + now.getMinutes()).substr(-2, 2);
    let hours = ("00" + now.getHours()).substr(-2, 2);
    return `${hours}:${min}`;
}

function log(message) {
    service.log(`[${getTime()}] ${message}`);
}

export function Trace() {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        if (AppSettings.logSeverity !== LogSeverity.Trace) return;
        log(`TRACE ${propertyKey}.enter()`);
    };
}

现在我有一个组件来读取日志

@Component({
    templateUrl: 'applicationlogs.template.html'
})
export class ApplicationLogsPage implements OnInit {
    logs: string[];
    private subscription: Observable<string>;
    constructor(private navCtrl: NavController, private $loggerService: LoggerService) { }

    ngOnInit(){
        this.subscription = this.$loggerService.applicationLog$.subscribe((s) => {
            this.logs = s.split(/\r\n|\r|\n/g);
        });
    }
}