Angular 是否有一个等效的异步管道可以在组件中使用?
在这样的组件中是否存在与Angular 是否有一个等效的异步管道可以在组件中使用?,angular,rxjs,reactive-programming,Angular,Rxjs,Reactive Programming,在这样的组件中是否存在与async管道等效的东西 @Component({ selector: 'my-component', }) export class myComponent { myObservable$: Observable<string>; method() { doSomething(this.myObservable$); // here I would like to
async
管道等效的东西
@Component({
selector: 'my-component',
})
export class myComponent {
myObservable$: Observable<string>;
method() {
doSomething(this.myObservable$);
// here I would like to access directly the current string value of
// myObservable$ without having to subscribe
}
}
@组件({
选择器:“我的组件”,
})
导出类myComponent{
myObservable$:可观察的;
方法(){
doSomething(这个.myObservable$);
//在这里,我想直接访问
//myObservable$无需订阅
}
}
你必须问问自己:通过避免subscribe()
调用,你想要实现什么?我的猜测是,您希望避免保留订阅和手动取消订阅
如果是这样的话,你只需要确保你得到了一个完整的可观测数据。那么以后就没有必要退订了。您可以将任何可观察的(有限或无限)转换为最终将完成的
以下是您案例的一个示例:
method() {
this.myObservable$.take(1).subscribe(
val => doSomething(val)
);
}
正确的方法实际上取决于你的可观察对象做了什么,以及你想对值做什么。例如,Angular2 http调用自己完成
或者,如果您想为您的可观察对象中的每个新值调用doSomething,则上述解决方案将不适用,因为您只获得第一个值,然后可观察对象就完成了。正如我所说,这可以归结为问题的背景。不,没有。您需要手动订阅和手动取消订阅以避免内存泄漏 对于简单订阅,您可能会尝试执行以下操作:
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
public myObservable$: Observable<string>;
private myObservableSub: Subscription;
ngOnInit() {
this.myObservableSub = this
.myObservable$
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {
this.myObservableSub();
}
}
可在以下位置找到此自定义运算符的实现:
原始答复
您应该做以下操作:
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
private componentDestroyed$ = new Subject<void>();
public myObservable1$: Observable<string>;
public myObservable2$: Observable<string>;
public myObservable3$: Observable<string>;
ngOnInit() {
this
.myObservable1$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
this
.myObservable2$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
this
.myObservable3$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}
}
@组件({
选择器:“我的组件”,
})
导出类myComponent实现OnInit、OnDestroy{
私有组件$=新主题();
公共Myobservable 1$:可观察;
公共myObservable2$:可观察;
公共肌肉可观测3$:可观测;
恩戈尼尼特(){
这
.肌肉可观测1$
.takeUntil(组件已销毁$)
.subscribe(=>{
//做点什么
});
这
.肌肉可观测2$
.takeUntil(组件已销毁$)
.subscribe(=>{
//做点什么
});
这
.肌肉可观测3$
.takeUntil(组件已销毁$)
.subscribe(=>{
//做点什么
});
}
恩贡德斯特罗(){
this.component.next();
this.component.complete();
}
}
如果你想了解更多,这里有一篇来自Ben Lesh的优秀文章:
编辑:多亏了@olsn,我编辑了我的答案并添加了带有
next
的行,因为一个完整的流确实不会阻止其他流
我创建了一个小Plunkr来演示这种行为:实现目标(不使用订阅)的唯一方法是使用BehaviorSubject,它有一个方法getValue()。观察对象和行为主体之间存在一些差异(你可以在中找到它们) 然而有一些关于stackoverflow的争论,为什么不使用getValue方法,而是使用subscription。。。然而,有一个可观察的take操作符将完成可观察序列(因此不必管理订阅)
如果您在
组件中
或有权访问ChangeDetectorRef
的组件中,您可以执行以下小技巧:
@Component({
...
providers: [AsyncPipe]
})
export class ExampleComponent {
app$ = this.sandbox.allApps$;
apps = this.pipeAsync.transform(this.app$);
contructor(
protected pipeAsync: AsyncPipe,
protected sandbox: AppAppsSandbox
) {}
}
这假设可以访问名为
AppAppsSandbox
的服务,但是可观察的应用程序$
可以来自任何地方,这是一种方便的打开方式。您可以使用我的库。您可以创建UserReader钩子并将其包装在AsyncPipe组件中。请看一个例子 你能描述一下这个案子吗?因为通常不需要这样做,所以任何数据转换都应该可以作为流写入。您的this.component.complete()
不会停止任何流,您需要调用.next()
,因为complete
只会完成流,但不会发出任何其他流可以做出反应的数据。@olsn谢谢,我编辑了这篇文章并引用了你的答案!takeUntil的例子解决了导致我提出这个问题的问题。
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
private componentDestroyed$ = new Subject<void>();
public myObservable1$: Observable<string>;
public myObservable2$: Observable<string>;
public myObservable3$: Observable<string>;
ngOnInit() {
this
.myObservable1$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
this
.myObservable2$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
this
.myObservable3$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}
}
var subject = new Rx.BehaviorSubject(current_subject_value);
subject.getValue()
this.myObservable$.take(1).subscribe()
@Component({
...
providers: [AsyncPipe]
})
export class ExampleComponent {
app$ = this.sandbox.allApps$;
apps = this.pipeAsync.transform(this.app$);
contructor(
protected pipeAsync: AsyncPipe,
protected sandbox: AppAppsSandbox
) {}
}