我需要創建服務,其中包含服務從服務器獲取的設置。這些設置是在應用程序中廣泛使用,而不是隻在一個地方: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