RxJs switchMap:哇,要传递多个值?
RxJs switchMap: wow to pass multiple values?
在 https://www.learnrxjs.io/recipes/smartcounter.html 我在 Angular 2+ 中找到了一个很好的数字计数器示例,代码如下所示:
@Component({
selector: 'number-tracker',
template: `
<h3> {{ currentNumber }}</h3>
`
})
export class NumberTrackerComponent implements OnDestroy {
@Input()
set end(endRange: number) {
this._counterSub$.next(endRange);
}
public currentNumber = 0;
private _counterSub$ = new Subject();
private _subscription : Subscription;
constructor() {
this._subscription = this._counterSub$
.switchMap(endRange => {
return timer(0, 20)
.mapTo(this.positiveOrNegative(endRange, this.currentNumber))
.startWith(this.currentNumber)
.scan((acc, curr) => acc + curr)
// .delayWhen(i => {
// easing here
// })
.takeWhile(this.takeUntilFunc(endRange, this.currentNumber));
})
.subscribe(val => this.currentNumber = val);
}
private positiveOrNegative(endRange, currentNumber) {
return endRange > currentNumber ? 1 : -1;
}
private takeUntilFunc(endRange, currentNumber) {
return endRange > currentNumber
? val => val <= endRange
: val => val >= endRange;
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
}
现在效果很好,但我想传递一个变量 currentNumber 而不是 this.currentNumber 默认值 0。
到目前为止,我已经走了这么远:
public currentNumber: number;
...
@Input()
set fanCountPrev(startRange: number) {
this.currentNumber = startRange
console.log('startRange: ', this.currentNumber)
}
...
但是当一个新值到来时,this.currentNumber没有设置为以前的版本。
您有任何提示或示例来完成此操作吗?
这里的问题是订阅是在构造函数上进行的,而 Input() 绑定是在 ngOnInit lifehook 上解析的。此外,在这种情况下,在运行时手动修改 this.currentNumber 变量并不是一个好习惯,可观察计算的内部状态也是如此。我认为唯一可行的方法是修改它 onInit,为此,正如我所说,您必须像这样在 ngOnInit lifehook 函数中创建订阅:
@Component({
selector: 'number-tracker',
template: `
<h3> {{ currentNumber }}</h3>
`
})
export class NumberTrackerComponent implements OnDestroy {
@Input()
set end(endRange: number) {
this._counterSub$.next(endRange);
}
@Input()
set fanCountPrev(startRange: number) {
this.currentNumber = startRange
console.log('startRange: ', this.currentNumber)
}
private currentNumber = 0;
private _counterSub$ = new Subject();
private _subscription : Subscription;
constructor() {
}
ngOnInit() {
this._subscription = this._counterSub$
.switchMap(endRange => {
return timer(0, 20)
.mapTo(this.positiveOrNegative(endRange, this.currentNumber))
.startWith(this.currentNumber)
.scan((acc, curr) => acc + curr)
// .delayWhen(i => {
// easing here
// })
.takeWhile(this.takeUntilFunc(endRange, this.currentNumber));
})
.subscribe(val => this.currentNumber = val);
}
private positiveOrNegative(endRange, currentNumber) {
return endRange > currentNumber ? 1 : -1;
}
private takeUntilFunc(endRange, currentNumber) {
return endRange > currentNumber
? val => val <= endRange
: val => val >= endRange;
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
}
但请记住,此解决方案仅适用于初始化。如果您在此组件存在期间更改变量,这将不起作用。但正如我所说,在这种情况下这不是一个好的做法,因为它是组件的内部计算状态,它只在初始化时才有意义。
希望对您有所帮助。
在 https://www.learnrxjs.io/recipes/smartcounter.html 我在 Angular 2+ 中找到了一个很好的数字计数器示例,代码如下所示:
@Component({
selector: 'number-tracker',
template: `
<h3> {{ currentNumber }}</h3>
`
})
export class NumberTrackerComponent implements OnDestroy {
@Input()
set end(endRange: number) {
this._counterSub$.next(endRange);
}
public currentNumber = 0;
private _counterSub$ = new Subject();
private _subscription : Subscription;
constructor() {
this._subscription = this._counterSub$
.switchMap(endRange => {
return timer(0, 20)
.mapTo(this.positiveOrNegative(endRange, this.currentNumber))
.startWith(this.currentNumber)
.scan((acc, curr) => acc + curr)
// .delayWhen(i => {
// easing here
// })
.takeWhile(this.takeUntilFunc(endRange, this.currentNumber));
})
.subscribe(val => this.currentNumber = val);
}
private positiveOrNegative(endRange, currentNumber) {
return endRange > currentNumber ? 1 : -1;
}
private takeUntilFunc(endRange, currentNumber) {
return endRange > currentNumber
? val => val <= endRange
: val => val >= endRange;
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
}
现在效果很好,但我想传递一个变量 currentNumber 而不是 this.currentNumber 默认值 0。
到目前为止,我已经走了这么远:
public currentNumber: number;
...
@Input()
set fanCountPrev(startRange: number) {
this.currentNumber = startRange
console.log('startRange: ', this.currentNumber)
}
...
但是当一个新值到来时,this.currentNumber没有设置为以前的版本。
您有任何提示或示例来完成此操作吗?
这里的问题是订阅是在构造函数上进行的,而 Input() 绑定是在 ngOnInit lifehook 上解析的。此外,在这种情况下,在运行时手动修改 this.currentNumber 变量并不是一个好习惯,可观察计算的内部状态也是如此。我认为唯一可行的方法是修改它 onInit,为此,正如我所说,您必须像这样在 ngOnInit lifehook 函数中创建订阅:
@Component({
selector: 'number-tracker',
template: `
<h3> {{ currentNumber }}</h3>
`
})
export class NumberTrackerComponent implements OnDestroy {
@Input()
set end(endRange: number) {
this._counterSub$.next(endRange);
}
@Input()
set fanCountPrev(startRange: number) {
this.currentNumber = startRange
console.log('startRange: ', this.currentNumber)
}
private currentNumber = 0;
private _counterSub$ = new Subject();
private _subscription : Subscription;
constructor() {
}
ngOnInit() {
this._subscription = this._counterSub$
.switchMap(endRange => {
return timer(0, 20)
.mapTo(this.positiveOrNegative(endRange, this.currentNumber))
.startWith(this.currentNumber)
.scan((acc, curr) => acc + curr)
// .delayWhen(i => {
// easing here
// })
.takeWhile(this.takeUntilFunc(endRange, this.currentNumber));
})
.subscribe(val => this.currentNumber = val);
}
private positiveOrNegative(endRange, currentNumber) {
return endRange > currentNumber ? 1 : -1;
}
private takeUntilFunc(endRange, currentNumber) {
return endRange > currentNumber
? val => val <= endRange
: val => val >= endRange;
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
}
但请记住,此解决方案仅适用于初始化。如果您在此组件存在期间更改变量,这将不起作用。但正如我所说,在这种情况下这不是一个好的做法,因为它是组件的内部计算状态,它只在初始化时才有意义。
希望对您有所帮助。