针对Angular中的SubjectvsBehaviorSubjectvsReplaySubject和angularinjectable这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Ang
针对Angular 中的 Subject vs BehaviorSubject vs ReplaySubject和angular injectable这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Angular 2事件发射器vs Subject、Angular 2路由器在Resolve中使用BehaviorSubject Observable、Angular BehaviorSubject 和错误异常、angular – BehaviorSubject过滤器不是一个函数?等相关知识,希望可以帮助到你。
本文目录一览:- Angular 中的 Subject vs BehaviorSubject vs ReplaySubject(angular injectable)
- Angular 2事件发射器vs Subject
- Angular 2路由器在Resolve中使用BehaviorSubject Observable
- Angular BehaviorSubject 和错误异常
- angular – BehaviorSubject过滤器不是一个函数?
Angular 中的 Subject vs BehaviorSubject vs ReplaySubject(angular injectable)
我一直在寻找了解这 3 个:
- 主题
- 行为主体
- 重播主题
我想使用它们并知道何时以及为什么,使用它们有什么好处,尽管我已经阅读了文档,观看了教程并搜索了谷歌,但我对此没有任何意义。
那么他们的目的是什么?一个真实的案例将不胜感激,它甚至不必编码。
我希望有一个清晰的解释,而不仅仅是“a+b => c you are subscribed to ....”
谢谢
答案1
小编典典它实际上归结为行为和语义。带一个
Subject
- 订阅者只会获得订阅 后 发出的发布值。问问自己,这是你想要的吗?订阅者是否需要了解有关先前值的任何信息?如果没有,那么您可以使用它,否则选择其他之一。例如,组件到组件的通信。假设您有一个组件在单击按钮时发布其他组件的事件。您可以使用带有主题的服务进行通信。BehaviorSubject
- 最后一个值被缓存。订阅者将在初始订阅时获得最新值。该主题的语义是表示随时间变化的值。例如登录用户。初始用户可能是匿名用户。但是一旦用户登录,那么新值就是经过身份验证的用户状态。
用BehaviorSubject
初始值初始化。这有时对编码偏好很重要。比如说你用null
.
然后在您的订阅中,您需要进行空检查。也许没问题,也许很烦人。
ReplaySubject
- 它可以缓存指定数量的排放。任何订阅者都将在订阅时获得所有缓存的值。你什么时候需要这种行为?老实说,我没有任何需要这种行为,除了以下情况:
如果您ReplaySubject
使用 的缓冲区大小初始化 a 1
,那么它实际上的 行为 就像 aBehaviorSubject
。最后一个值总是被缓存,所以它就像一个随时间变化的值。有了这个,就不需要像用 a
初始化null
的情况那样进行检查了。在这种情况下,在第一次发布之前,不会向订阅者发送任何值。BehaviorSubject``null
所以它真的归结为你所期望的行为(至于使用哪一个)。大多数时候,您可能想要使用
aBehaviorSubject
因为您真正想要表示的是“随时间变化的价值”语义。ReplaySubject
但我个人认为用初始化的替换没有任何问题1
。
当你真正需要的是一些缓存行为时,你想要 避免 的是使用 vanilla
。Subject
例如,您正在编写路由保护或解析。您在该守卫中获取一些数据并将其设置在
serviceSubject
中。然后在路由组件中订阅服务主题以尝试获取在防护中发出的值。哎呀。价值在哪里?它已经发出了,DUH。使用“缓存”主题!
Angular 2事件发射器vs Subject
dataRefreshEvent = new EventEmitter(); private companyDataAnnouncedSource = new Subject(); companyDataAnnouncedSource$= this.companyDataAnnouncedSource.asObservable();
Angular2团队强调了这样一个事实,即EventEmitter不应该用于组件和指令中的@Output()之外的任何其他东西.
Angular团队has stated,他们可能会改变EventEmitter的底层实现,并破坏使用EventEmitter的用户代码,而不是用于它的目的.这是主要的区别.
Angular 2路由器在Resolve中使用BehaviorSubject Observable
这是我的服务:
@Injectable() export class MyService { private _data: BehaviorSubject<Array<string>> = new BehaviorSubject(undefined); constructor() {} public getData(): Observable<Array<string>> { this._data.next(['test1','test2','test3']); let asObservable = this._data.asObservable().delay(1000); asObservable.subscribe((myData) => { console.log([myData,'this console message DOES show up']); }); // if I return here,my component's constructor and ngOnInit never fire // return asObservable; let fakeObservable = Observable.of(['test1','test3']).delay(1000); fakeObservable.subscribe((fakeData) => { console.log([fakeData,'this console message shows up']); }); console.log([asObservable,fakeObservable]); /* console log output Observable { _isScalar: false,operator: DelayOperator,source: Observable { _isScalar: false,source: BehaviorSubject { _isScalar: false,_value: ['test1','test3'],closed: false,hasError: false,isstopped: false,observers: Array[1],thrownError: null,value: ['test1','test3'] } } },Observable { _isScalar: false,source: ScalarObservable { _isScalar: true,scheduler: null,'test3'] } } */ return fakeObservable; // this WILL reach my component constructor and ngOnInit } }
这是我的决心
@Injectable() export class MyResolver implements Resolve<Array<string>> { constructor(private myService: MyService) {} resolve(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<Array<string>>|undefined { return this.myService.getData(); } }
这是路由器
RouterModule.forChild([{ path: 'mypath',component: MyComponent,resolve: { data: MyResolver } }]);
这是组件:
@Component({ selector: 'my-component',template: '<Span>My Component</span>' }) export class MyComponent implements OnInit { constructor(private route: ActivatedRoute) { console.log('component constructor'); } ngOnInit(): void { console.log(this.route.snapshot.data['data']); // ['test1','test3'] } }
这可能不是设计解决方案和服务之间交互的最佳方式,因此我对那里的建议非常开放.但是,如果我不弄清楚为什么BehaviorSubject.asObservable()不起作用,我可能会发疯,但模拟的observable确实有效.
解决方法
Angular BehaviorSubject 和错误异常
你不能简单地做一些像设置你的行为主题形状这样的事情:
data$ = new BehaviorSubject({
users: [],error: null,create: false
});
并在您发现错误时设置 error
属性:
private createUser(user: User){
this.http.post({body : user}).pipe(
map((result) => result),catchError((err) => {
if (err.error?.title === 'Custom' && err.status === 400) {
////Get and return exception
this.data$.next({...this.data$.value,error: 'Your error message about the is statement'}); // Maybe err.message,whatever you want
return throwError(err);
} else {
// Same here with error message about your else statement
return throwError(err);
}
// And you should think about a default error message,err.message or whatever is returned
})
)
.subscribe((response: any) => {
if(response) {
this.data$.next({...this.data$.value,create: true});
}
});
}
因此您将能够处理组件中的错误字段:
this.userService.data$.subscribe((data) => {
if(!data.error) {
this.router.navigate(['/users/user/list']);
}
// You can also display a snackbar with the error message if you want. Adapt it with your need,maybe you only want a boolean
});
angular – BehaviorSubject过滤器不是一个函数?
https://plnkr.co/edit/JHODQeWQtYmz4UkYzFds?p=preview
错误附加在以下行
let load = this.actions$.filter (action => return action.type==START_LOADING);
actions $定义如下:
private actions$: BehaviorSubject<Action> = new BehaviorSubject<Action>({type: null,payload: null});
我导入了这个
import { Subject } from "rxjs/subject"; import { Observable } from "rxjs/Observable"; import { BehaviorSubject } from 'rxjs/subject/BehaviorSubject';
在Chrome的调试器中,我看到一些功能可用(地图,电梯,扫描等)但不过滤.
有人知道为什么过滤器在BehaviorSubject上不可用?我想这是一个简单的错误,但我找不到;)
解决方法
import 'rxjs/add/operator/filter';
这是您更新的plunkr与此导入:https://plnkr.co/edit/37JEG4aQ7qmQuaPchB4Z?p=preview.
有关详细信息,请参阅此问题:
> Angular 2 HTTP GET with TypeScript error http.get(…).map is not a function in [null]
关于Angular 中的 Subject vs BehaviorSubject vs ReplaySubject和angular injectable的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Angular 2事件发射器vs Subject、Angular 2路由器在Resolve中使用BehaviorSubject Observable、Angular BehaviorSubject 和错误异常、angular – BehaviorSubject过滤器不是一个函数?等相关知识的信息别忘了在本站进行查找喔。
本文标签: