我以为我终于开始明白了这一点,但显然我仍然缺少一些东西。我正在尝试使用我的应用程序设置服务中的BehaviorSubject创建observable。我想我理解正确创建observable的步骤。但是现在当我有一些新的值来更新observable时,Angular会破解运行时告诉我接下来的行为服务是未定义的。
这是更新的代码:
import { Input } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { BehaviorSubject } from 'rxjs';
import { AppSettings } from '../shared/app-settings';
import { APPSETTINGS } from "../shared/defaultSettings";
import { Inject, Injectable } from '@angular/core';
import { LOCAL_STORAGE, StorageService } from 'angular-webstorage-service';
import { LogService } from 'src/app/services/app-log.service';
@Injectable()
export class AppSettingsService {
className: string;
settings: AppSettings;
@Input()
// Use of BehavioirSubject. This is where you post values into
private _settings$: BehaviorSubject<AppSettings> = new BehaviorSubject<AppSettings>(APPSETTINGS)
// Settings observer. This is where you read from outside
settings$: Observable<AppSettings> = this._settings$.asObservable();
constructor(private logger: LogService,
@Inject(LOCAL_STORAGE) private storage: StorageService) {
this.className = this.constructor.toString().match(/\w+/g)[1];
/*
* First, we check to see if this is the first time the app has
* been run on this machine. If it is, then local storage will return
* null when we ask for the settings. We'll populate local storage
* with the default settings values before we continue on setting up
* the service.
*/
this.settings = this.storage.get('TRACS3_SETTINGS');
if ( this.settings == null ) {
try {
this.storage.set('TRACS3_SETTINGS', APPSETTINGS);
}
catch(e) {
console.log(this.className, 'Machine does not support local storage. ');
}
}
/*
AppSettings are now initialized, set the initial value of them for all other
components will use to monitor them.
*/
console.log(this.className, 'about to set observable iniitial values');
this.settings = this.storage.get('TRACS3_SETTINGS');
this._settings$ = this.storage.get('TRACS3_SETTINGS');
console.log(this.className, 'just changed observabe to ', this._settings$);
}
public saveSettings(settings: AppSettings): void{
console.log(this.className, 'saving settings in service, new settings: ', settings);
//this._settings$.post(settings)
this.storage.set('TRACS3_SETTINGS', settings);
this._settings$.next( settings );
}
//public getSettings(): AppSettings {
//eturn this.storage.get('TRACS3_SETTINGS');
//}
}
现在我得到了不同的错误。如果我尝试用这行代码设置Observer:
this._settings$ = this.settings;
我收到错误消息:
Type 'AppSettings' is missing the following properties from type 'BehaviorSubject<AppSettings>': _value, value, _subscribe, getValue, and 19 more.ts(2740)
但当我把它放到上面显示的值(= this.storage.get ...)时,我现在得到运行时错误
我在这里结束了我的智慧。除了可能完全放弃角度之外,我不知道还有什么。
在你的构造函数中,你用_settings$
重新分配this._settings$ = this.storage.get('TRACS3_SETTINGS');
现在这个领域是TRACS3_SETTING
的价值,我想这不是任何一种Observable。
您应该使用this._settings$.next(this.storage.get('TRACS3_SETTINGS'));
来更改其内部值
我问一位工程师(@JavRufus)正在研究这个问题(多年来我没有编写代码,而是再次自学艺术)。他为我想出了以下例子。
appsettings.service.ts:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { AppSettings } from '../model/appsettings';
@Injectable({
providedIn: 'root'
})
export class AppSettingsService {
private appSettings: AppSettings;
private _appSettingsSubject: BehaviorSubject<AppSettings> = new BehaviorSubject(this.appSettings);
constructor() {
if (localStorage && localStorage.getItem('APP-SETTINGS') !== 'undefined') {
this.appSettings = JSON.parse(localStorage.getItem('APP-SETTINGS'));
} else {
this.appSettings = new AppSettings();
localStorage.setItem('APP-SETTINGS', JSON.stringify(this.appSettings));
}
this._appSettingsSubject.next(this.appSettings);
}
get behaviorSubject() {
return this._appSettingsSubject;
}
set updateAppSettings(newAppSettings: AppSettings) {
console.log('Service; update sessings: ' + this.appSettings.userName + '; ' + this.appSettings.password);
this.appSettings = newAppSettings;
if (localStorage) {
localStorage.setItem('APP-SETTINGS', JSON.stringify(this.appSettings));
}
this._appSettingsSubject.next(this.appSettings);
}
}
样品client.component.ts:
import { Component, OnInit } from '@angular/core';
import { AppSettings } from '../model/appsettings';
import { AppSettingsService } from '../config/appsettings.service';
@Component({
selector: 'app-sample-client',
templateUrl: './sample-client.component.html',
styleUrls: ['./sample-client.component.css']
})
export class SampleClientComponent implements OnInit {
appSettings: AppSettings;
constructor(private appSettingsService: AppSettingsService) {}
ngOnInit() {
this.appSettings = this.appSettingsService.behaviorSubject.getValue();
}
updateAppSettings() {
console.log('Client; update sessings: ' + this.appSettings.userName + '; ' + this.appSettings.password);
this.appSettingsService.updateAppSettings = this.appSettings;
}
}
最后,接着是sample-receiver.component.ts:
import { Component, OnInit } from '@angular/core';
import { AppSettings } from '../model/appsettings';
import { AppSettingsService } from '../config/appsettings.service';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-sample-receiver',
templateUrl: './sample-receiver.component.html',
styleUrls: ['./sample-receiver.component.css']
})
export class SampleReceiverComponent implements OnInit {
appSettings: AppSettings;
appSettingsSub: Subscription;
constructor(private appSettingsService: AppSettingsService) {}
ngOnInit() {
this.appSettings = this.appSettingsService.behaviorSubject.getValue();
this.appSettingsSub = this.appSettingsService.behaviorSubject.asObservable().subscribe(value => {
this.appSettings = value;
});
}
}
当然是appsettings.ts类
export class AppSettings {
userName: string;
password: string;
constructor() {}
}
使用此作为起点,您应该没有问题设置服务来保存appSettings然后有一个组件来修改它们和一个组件来接收它们的变化通知。
希望这将有助于其他人不花3天时间寻找像我一样的解决方案!