行为主体初始值为空?

时间:2017-06-22 07:55:00

标签: angular typescript rxjs

private customer: Subject<Object> = new BehaviorSubject<Object>(null);

setCustomer(id, accountClassCode) {
    this.customer.next({'id': id, 'accountClassCode': accountClassCode});
}

getCustomer() {
    return this.customer.asObservable();
}

我正在使用这部分代码,但是我收到的错误是找不到null的id。是否有任何解决方案可以获得非空的初始值?

3 个答案:

答案 0 :(得分:54)

BehaviorSubject的目的是提供初始价值。它可以是null或其他任何内容。如果无法提供有效的初始值(当用户ID尚未知晓时),则不应使用它。

ReplaySubject(1)提供了类似的行为(在订阅时发出最后一个值),但在使用next设置之前没有初始值。

可能应该是

private customer: Subject<Object> = new ReplaySubject<Object>(1);

答案 1 :(得分:2)

尝试以这种方式构建您的服务:

<强>服务

@Injectable()
export class MyService {
    customerUpdate$: Observable<any>;

    private customerUpdateSubject = new Subject<any>();

    constructor() {
        this.customerUpdate$ = this.customerUpdateSubject.asObservable();
    }

    updatedCustomer(dataAsParams) {
        this.customerUpdateSubject.next(dataAsParams);
    }
}

请务必向提供商添加MyService

在您更新客户端的地方(如果是这种情况),您可以执行以下操作:

组件(触发的组件):

constructor(private myService: MyService) {
        // I'll put this here, it could go anywhere in the component actually
        // We make things happen, Client has been updated
        // We store client's data in an object
        this.updatedClient = this.myObjectWithUpdatedClientData;  // Obj or whatever you want to pass as a parameter
        this.myService.updatedCustomer(this.updatedClient);
    }

组件(已订阅的组件):

this.myService.customerUpdate$.subscribe((updatedClientData) => {
            // Wow! I received the updated client's data
            // Do stuff with this data!
        }
    );

根据我的理解,您正在尝试将数据从1个组件传递到另一个组件。您获取客户的数据并通过您的应用程序发送到另一个组件,对吗?这就是我发布此解决方案的原因。

如果您对其他类型的订阅感兴趣,请阅读:

Angular 2 special Observables (Subject / Behaviour subject / ReplaySubject)

答案 2 :(得分:0)

我发现许多情况下,我既想要ReplaySubject(1)的简单性,又想要value的{​​{1}}属性,即它存储了您最近的值以供检索而无需订阅。考虑到需要广播的初始值,使用BehaviorSubject总是很烦人,这是我很少想要的条件。为此,我创建了自己的BehaviorSubject

CurrentSubject

我想重写import { ReplaySubject } from "rxjs"; export class CurrentSubject<T> extends ReplaySubject<T> { value: T; set(value?: T) { this.value = value; this.next(value); } } 方法,但是由于某种原因我无法使它起作用,所以我选择了一种名为next的方法。我的替代尝试看起来像这样...

set

我不知道为什么覆盖无效。