Angular,RxJS:为具有AsyncSubject源的Observable分配新值

时间:2017-10-18 04:19:14

标签: angular rxjs

我需要创建包含服务从服务器获取的设置的服务。这些设置在应用程序中广泛使用,而不是仅在一个地方使用:

@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,因为我的设置是特定于用户的,因此用户必须先登录。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您希望将值发送到 settingsSubject$ ,以便settings$上的订阅者在下游接收它们:

public update(settings: Settings) {
  return this.jsonApiService.post(`${this.apiResource}`, settings)   
    .do(() => {
      this.settingsSubject$.next(settings);
    });       
}