我需要创建服务,其中包含服务从服务器获取的设置。这些设置是在应用程序中广泛使用,而不是只在一个地方:Angular,RxJS:为具有AsyncSubject源的Observable分配一个新值
@Injectable()
export class SettingsService {
private apiResource = '/settings';
private settingsSubject$: AsyncSubject<Settings> = new AsyncSubject();
public settings$: Observable<Settings> = this.settingsSubject$.asObservable();
constructor(private jsonApiService: JsonApiService) {
}
public init(): void {
this.get()
.subscribe(settings => {
this.settingsSubject$.next(settings);
this.settingsSubject$.complete();
});
}
public update(settings: Settings) {
return this.jsonApiService.post(`${this.apiResource}`, settings)
}
private get() {
return this.jsonApiService.get(`${this.apiResource}`);
}
}
我把加载数据init
方法和CoreModule为了调用它来获得应用程序启动数据:
export class CoreModule {
constructor(private settingsService: SettingsService) {
this.settingsService.init();
}
正如你所看到的,我使用AsyncSubject
来强制所有用户在请求完成时等待。
问题是如何调用update
函数时调用一个新值? 我试过使用:
public update(settings: Settings) {
return this.jsonApiService.post(`${this.apiResource}`, settings)
.do(() => {
this.settings$ = Observable.of(settings);
});
}
但没有任何反应。而且,我认为这不是一个正确的方法。
PS。使用的一个示例:
export class SettingsComponent implements OnInit {
public settings: Settings;
public settingsForm: FormGroup;
constructor(private settingsService: SettingsService,
private fb: FormBuilder) {
}
ngOnInit() {
this.settingsService.settings$
.subscribe(data => {
this.settings = data;
this.settingsForm = this.fb.group({
corValue: [this.settings.corValue],
});
});
}
}
<div *ngIf="settings">
<form [formGroup]="settingsForm">
...
</form>
</div>
另一个用途是服务:
@Injectable()
export class CalculationService {
private corValue: number;
constructor(private settingsService: SettingsService) {
this.settingsService.settings$
.subscribe(settings => {
this.corValue = settings.corValue;
})
}
... different functions that make some math calculations and some functions use corValue.
}
PS2。我无法使用APP_INITIALIZER
,因为我的设置是用户特定的,所以用户必须先登录。
你不能。 “AsyncSubject”存在,以便所有当前和未来的订户从AsyncSubject订阅的源接收** last **值。主题通常用于连接观察者;您明确地向主题提供了值,但效果是相同的:订户收到最后一个值。如果这不是你想要的行为,那么一个普通的'Subject'可能就是你应该使用的。此外,完成一个可观察的信号给用户,有**没有进一步的价值**,实际上,用户将自动取消订阅。 – cartant
@cartant'主题'是我第一次尝试。我在问题中加入了一些代码。在那里你可以看到我订阅了'settings $'并注意模板中的'ngIf'。所以,当我使用'Subject'时,有时候我没有看到表单,有时会显示,我认为这是因为请求没有完成或其他。使用'AsyncSubject'我没有这样的问题。 – user348173