【问题标题】:Subscribing for Observable in service angular is not working在服务角度订阅 Observable 不起作用
【发布时间】:2017-11-26 20:34:32
【问题描述】:

我正在使用 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 的有效方式,请告诉我。

TechnicalIndicator.service.ts

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

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

【问题讨论】:

  • 你为什么要传递一个 observable 给你的服务。为什么不每次需要更新指标时直接调用服务的方法呢?一个组件通常有几个实例。每次创建 TradeComponent 时,它都会创建一个新的 observable 并将其传递给服务。
  • 能否包含组件的@Component注解?
  • 请查看编辑后的代码。我的组件类中有 2 个订阅,priceUpdate 和 oldPriceUpdate。两者都会将数据传递给服务,并且在服务中数据必须同步(因为我正在使用它来更新我的数组)。在某些情况下,事情并没有按预期工作。因此,与其直接调用方法,不如考虑使用可观察对象并传递数据。
  • @echonax 我已在我的实际代码中添加。这里我没有添加以减少代码长度。
  • @AnuPai 所以你的组件上面没有@Component 注释?喜欢:angular.io/tutorial/toh-pt1#the-road-youve-travelled

标签: angular rxjs observable behaviorsubject


【解决方案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:

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

价格分量

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

    }
}

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

【讨论】:

  • 您还必须处理来自 TechnicalIndicatorService 的订阅。
【解决方案2】:

你好朋友,你应该在顶层模块中提供它

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 {
}

【讨论】:

    猜你喜欢
    • 2021-10-07
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 2017-08-12
    • 2019-05-14
    • 2019-02-04
    相关资源
    最近更新 更多