在服务角度订阅Observable不起作用

时间:2017-06-23 09:53:57

标签: angular rxjs observable behaviorsubject

我正在使用角度分量和学习东西的Rxjs observable。我有一个场景,我需要根据一些事件将数据从组件传递到服务。

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获得新价格后,我有另一项服务,我正在进行一些技术研究。我需要将数据传递给服务,我正在使用组件中的行为主题,而Service正在订阅它。 (与组件订阅的常规方法不同。)

如果它是使用observable的有效方法,请告诉我。

TechnicalIndicator.service.ts

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

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

2 个答案:

答案 0 :(得分:0)

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

根据您所写的内容,我了解您要通知TechnicalIndicatorService执行priceUpdateoldPriceUpdate更改。

解决方案1:

为此你根本不需要来组件。你可以这样做。直接将PriceService注入TechnicalIndicatorService

TechnicalIndicatorService:

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

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

解决方案2:

但是你不希望他们彼此意识到并且只想从Component做,那么你可以这样做:

<强> PriceComponent

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

    }
}

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

答案 1 :(得分:0)

您好,您应该在顶级模块中提供它

DECLARE @cols AS NVARCHAR(MAX),  @query AS NVARCHAR(MAX);
                        
SELECT @cols = 
       STUFF((SELECT DISTINCT ',' + 
                     CONCAT('SUM(CASE WHEN [Item]=''',[Item],
                                            ''' THEN [Quantity] END) AS [',[Item],']') 
                  AS formulas
                FROM 
                (
                 SELECT DISTINCT [Item]
                   FROM [InvoiceInfo] f
                ) ff
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'');
       
SET @query = CONCAT(
    N'SELECT [Invoice], [Date], [BaseCard],', @cols , 
    N'      ,SUM([Price]*[Quantity]) AS [Subtotal],
             SUM(ROUND([Price]*[Quantity]*.16, 2)) AS [Taxes],
             SUM([Price]*[Quantity])+SUM(ROUND([Price]*[Quantity]*.16, 2)) AS [Total]
        FROM [InvoiceInfo] i
       GROUP BY [Invoice], [Date], [BaseCard]');

EXEC sp_executesql @query; 

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

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