让我们编写一个简单的示例,该示例每1秒递增一次,用户| sync
将更新模板:
@Component({
selector: 'my-counter',
templateUrl: '
</div> {{time | async}}</div>
<button (click)="stop()"> stop counter</button>'
})
export class AppComponent implements OnInit {
counter: Observable<any>;
ngOnInit() {
this.counter = interval(1000).pipe(
map(i => `Result ${i}`)
);
}
stop() {
this.counter.unsubscribe(); // error. no such thing unsubscribe()
}
activate() {
this.counter /// ???
}
}
但是现在模板通过Subscription
方法获得了unsubscribe
值的处理程序。
那我该如何停止柜台?
在我停止它之后,有一种方法可以再次激活?
答案 0 :(得分:2)
您可以使用takeUntil
运算符,该运算符将监听第二个Observable
,并在听到事件时取消订阅。例如,在下面的代码中,我们创建一个名为Subject
的{{1}}。只要我们在stop$
上发出一个值,我们的订阅就会结束
stop$
答案 1 :(得分:1)
在Rx中,当您订阅任何可观察项时,您将获得一次性订阅: 这是可观察的基本契约:
Observable<T>.subscribe(observer: Observer<T>) : Subscription
在您的示例中,counter
不是订阅,它本身是可观察的。
如果要基于外部条件终止可观察对象,则可以使用诸如takeUntil
或takeWhile
之类的限制运算符来完成可观察序列。当可观察对象完成或引发错误时,将处理所有订阅。
要创建可以从外部触发的计时器:
let startStop = new Rx.Subject()
let counter =
startStop
.startWith(false)
.switchMap(v => v ? Rx.Observable.interval(1000) : Rx.Observable.empty())
.select((_, i) => i)
counter.subscribe(x => console.log(x)) //print
//start timer
startStop.onNext(true)
//stop timer
startStop.onNext(false)
答案 2 :(得分:0)
我尝试使用不同的方法,而不是使用Observer
来使用Subject
;
@Component({
selector: 'my-counter',
templateUrl: `
</div> {{time | async}}</div>
<button (click)="stop()"> stop counter</button>
`
})
export class MyCounter implements OnInit {
counter: Subject<any>;
value = 0;
ngOnInit() {
this.counter = new Subject();
setInterval(_ => {
this.counter.next( this.value++ );
},1000);
}
stop() {
this.counter.unsubscribe(); // work now
}
activate() {
this.counter /// ???
}
}