1

我正在使用 Rxjs 在角度组件中可观察到并学习东西。我有一个场景,我需要根据某些事件将数据从组件传递到服务。

Price.service.ts

export class PriceService{
   private priceUpdate: BehaviorSubject<Object> = new BehaviorSubject({});
   private oldPriceUpdate: BehaviorSubject<Object> = new BehaviorSubject({});
   getPriceUpdate(){
       return this.priceUpdate.asObservable();
   }
  getOldPrice(){
      return this.oldPriceUpdate.asObservable();
  }
}

以上服务用于组件中获取价格更新。

Price.component.ts

@Component({
  selector: 'price',
  templateUrl: 'price.component.html',
  styleUrls: ['price.component.css']
})
export class PriceComponent{
    updateIndicator: BehaviorSubject<Object> = new BehaviorSubject({});
  constructor(private priceService:PriceService, private techIndicator:TechnicalIndicatorService){
    this.techIndicator.subscribeUpdateIndicator(this.updateIndicator.asObservable());
    this.priceService.getPriceUpdate().subscribe(
      (newPrice:any) => {
         this.updatePrice(newPrice);
      }
    )
   this.priceService.getOldPriceUpdate().subscribe(
     (oldPrice:any ) => {
        //some business logic
        this.updateIndicator.next({{data: data, ....});
    });
  }
  private updatePrice(newPrice:any){
     //.... some business logic.... 
      this.updateIndicator.next({data: data, ....});
  }
}

在组件中从 PriceService 获得新价格后,我有另一项服务,我正在做一些技术研究。我需要将数据传递给服务,为此我使用组件中的行为主题并且服务正在订阅它。(与组件订阅的通常方法不同。)

请让我知道它是否是使用 observable 的有效方式。

技术指标.service.ts

export class TechnicalIndicatorService{
    subscribeUpdateIndicator(updateIndicator:Observable<Object>){
     updateIndicator.subscribe(
         (obj:any) => {
          // some logic
         });
    }
}

但是,订阅在 TechnicalIndicatorService 中只工作一次。对于之后的任何数据更新,它都不会触发订阅。请让我知道我在这里缺少什么。

4

2 回答 2

1

你有太多的主题。您可以阻止它们并使其更简单。

根据您所写的内容,我了解您想通知TechnicalIndicatorService做某事priceUpdateoldPriceUpdate更改。


解决方案1:

为此,您根本不需要使用组件。你可以这样做。直接PriceService注入TechnicalIndicatorService

技术指标服务:

export class TechnicalIndicatorService{
    constructor(private priceService: PriceService){
       priceService.getPriceUpdate().subscribe(this.doSomething);
       priceService.getOldPrice().subscribe(this.doSomething);
    }
    private doSomething(update){
    }
}

你不需要在组件中写任何东西。


解决方案2:

但是您不希望他们彼此了解并且只想从 Component 做,那么您可以这样做:

价格成分

export class PriceComponent{
   constructor(
       private priceService:PriceService,
       private techIndicator:TechnicalIndicatorService
   ){
       this.techIndicator.subscribeUpdateIndicator(
          return Observable.merge(
             priceService.getPriceUpdate(),
             priceService.getOldPrice()
          );
       );

    }
}

如果您仍想使用主题,请告诉我,我会检查它们失败的原因。

于 2017-06-24T18:28:06.590 回答
0

你好,伙计,你应该在顶层模块中提供它

import { Post } from './../contance/models/posts';
import { Subject } from 'rxjs';
import { Injectable } from '@angular/core';
import { USER, User } from '../contance';
import { usersState } from './states/users.state';
import { deleteFromArray, updateArray } from '../utils/array-utils';

@Injectable({
  providedIn: 'root'
})
export class StoreService {
  state = {
    usersState,
  }
  private Posts = new Subject<Post[]>()
  posts = this.Posts.asObservable()
  constructor() {
  }

  getUser() {
    if (localStorage.getItem(USER)) {
      return JSON.parse(localStorage.getItem(USER)) as User
    }
  }

  public postsActions = {
    fetch: (posts: Post[]) => this.Posts.next(posts),
    delete: (id: number) => deleteFromArray('id', id, this.Posts.observers),
    edit: (object: Post) => updateArray('id', object.id, this.Posts.observers, object, true)
  }
}

您需要在 app.module 中提供服务:

/**
 * @license
 * Copyright Akveo. All Rights Reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 */
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
import { CoreModule } from './@core/core.module';
import { ThemeModule } from './@theme/theme.module';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import {
  NbChatModule,
  NbDatepickerModule,
  NbDialogModule,
  NbMenuModule,
  NbSidebarModule,
  NbToastrModule,
  NbWindowModule,
} from '@nebular/theme';
import { HttpRequestModule } from './@core/interceptor/http-request.module';
import { StoreService } from './@core/context/store.service';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpRequestModule,
    AppRoutingModule,
    NbSidebarModule.forRoot(),
    NbMenuModule.forRoot(),
    NbDatepickerModule.forRoot(),
    NbDialogModule.forRoot(),
    NbWindowModule.forRoot(),
    NbToastrModule.forRoot(),
    NbChatModule.forRoot({
      messageGoogleMapKey: 'AIzaSyA_wNuCzia92MAmdLRzmqitRGvCF7wCZPY',
    }),
    CoreModule.forRoot(),
    ThemeModule.forRoot(),
  ],
  providers: [StoreService],
  bootstrap: [AppComponent],
})
export class AppModule {
}

于 2020-12-02T16:17:42.257 回答