我目前正在尝试使用RxJS创建一个演示Reactive Programming的小项目。我的目标是向同事们展示这件事情已经存在,值得研究。 我对框架没有经验,所以这会让事情变得复杂。
我正在试图扩展我的另一个演示以利用RxJS。 这不是一个非常复杂的演示,基本上我可以添加任意数量的小形式,它们会产生一个由小公式计算的数字,并且有一个按钮,总结所有形式的值。
在表格内部计算公式很容易,但我想我可以更进一步。
我希望通过合并的observable自动完成sum操作。 我想出的唯一解决方案是:
//dummy observables
var s1 = Rx.Observable.Interval(100);
var s2 = Rx.Observable.Interval(200);
//Combine the observables
var m = s1.combineLatest(s2, function(x,y){return x+y});
//Subscribe to the combined observable
var sub = m.subscribe(function(x){console.log(x)});
//A new observable is created
var s3 = Rx.Observable.Interval(300);
//Now I need to update all my subscriptions, wich is a pain.
m = m.combine(s3, function(x,y){return x+y});
sub.dispose();
sub=m.subscribe(function(x){console.log(x)});
我想我可以得到另一个observable来通知我的订阅者自我更新 - 因为知道我的所有订阅者的工作会使整个架构变得毫无用处,但这对于像这样的任务来说听起来有点过分,而且我不会这样做。只是意味着演示,我真的无法想象每天都会有#34;"现实世界的例子,像这样的架构会让事情变得更干净,而不仅仅是观察任何变化,并且积极地获得计算出来的值"从我的表格。 我可能会对处理表单的模块中的值进行主动获取和求和,并使用" m"可以观察外部世界订阅,从模块内部将我的值推入其中。
这是一种正确的方法吗?我认为是的,因为它们归我的模块所有,我应该完全控制它们发生的事情,但我真的对更有经验的人对此的看法感兴趣。
答案 0 :(得分:1)
我认为您不会找到直接做您需要的操作员。
虽然制作自己的运营商没有错:
var source = //An observable of observables of form data
Observable.prototype.combineLatestObservable = function(resultSelector) {
var source = this;
return Rx.Observable.create(function(obs) {
var disposable = new Rx.SerialDisposable();
var sources= [];
return source.subscribe(
function(x) {
//Update the set of observables
sources.push(x);
//This will dispose of the previous subscription first
//then subscribe to the new set.
disposable.seDisposable(Rx.Observable.combineLatest(sources, resultSelector)
.subscribe(obs));
},
function(e) { obs.onError(e); },
function() { obs.onCompleted(); });
}).share();
}
或者如果您想要与运营商合作:
//Have to use arguments since we don't know how many values we will have
function sums() {
var sum = 0;
for (var i = 0, len = arguments.length; i < len; ++i) {
sum += arguments[i];
}
return sum;
}
source
//Capture the latest set of Observables
.scan([], function(acc, x) {
acc.push(x);
return acc;
})
//Dispose of the previous set and subscribe to the new set
.flatMapLatest(function(arr) {
return Observable.combineLatest(arr, sums);
})
//Don't know how many subscribers you have but probably want to keep from
//recreating this stream for each
.share();
答案 1 :(得分:1)
我正在使用此片段合并未知数量的可观察量 -
someArrayOfIdsToPerformRequest: [];
this.isLoading = true;
const mergedRequests: Array<Promise<JSON>> = [];
this.someArrayOfIdsToPerformRequest.forEach((item) => {
mergedRequests.push(this.postsService.remove({id: item.id}) //returns observable
.toPromise());
});
Promise.all(mergedRequests)
.then(() => {
this.isLoading = false;
this.loadPosts();
});
希望这有助于某人!
答案 2 :(得分:0)
如果你看一下combineLatest
Observable
你可以看到,它需要一个可变数量的// Whatever Observables you want...
const a = Rx.Observable.of(1,2,3)
const b = Rx.Observable.interval(100).take(5)
const c = Rx.Observable.of(2)
Rx.Observable.combineLatest(a, b, c) // notice, I didn't define a resultSelector
.do(numbers => console.log(numbers)) // you get 3 element arrays
.map(numbers => numbers.reduce((sum, n) => sum + n, 0))
.subscribe(sum => console.log(sum))
,而不仅仅是一个[3, 0, 2] // array printed in the do block
5 // the sum of the array printed from the subscription
[3, 1, 2]
6
[3, 2, 2]
7
[3, 3, 2]
8
[3, 4, 2]
9
。考虑到这一点,你可以做这样的事情:
Observable
我的例子的输出将是:
Function#apply
如果您想使用Rx.Observable.combineLatest.apply(Rx.Observable, [a, b, c])
数组调用此标记,可以使用getSupportActionBar().setDisplayShowTitleEnabled(true);
getSupportActionBar().setTitle("Hello");
执行此操作:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
希望我没有误解你的要求
答案 3 :(得分:0)
我知道我参加这个聚会迟到了,但是我只是有同样的问题,无法找到合适的答案。我已经弄清楚了如何在我的应用程序上下文中执行此操作,因此,除非这仍然是您的未解决问题,否则我将在此处发布答案以供后代参考。
要设置我的问题,我有一个带有许多控件的Angular表单。每当验证状态在任何一个控件上更改时,我都需要做一些事情。但是,控件可以在以后动态添加到表单中,我仍然需要侦听这些单独控件上的验证更改。
我将尝试稍微改变我的方法以适应问题的背景。基本上,是的,正确的方法是在何时让内部Observable更新其订阅时使用外部Observable信号。这是可以接受的体系结构,坦率地说,这是Reactive Extensions如此强大的原因之一。这是我使用RxJS 6.2.2和TypeScript 3.0.1做到的方式。请注意,在询问或先前回答此问题时,此方法可能不可用。
import { map, mergeMap, delay } from 'rxjs/operators';
import { interval, Subject, Observable } from 'rxjs';
// utility function to create sample observables
const createObs = (time: number, i: string) => interval(time).pipe(map(val => `${i}: ${val}`))
// create static sample observables.
// these could represent the value changes of known form elements
const obsA = createObs(1000, 'A'); // emit every 1 second
const obsB = createObs(2500, 'B'); // emit every 2.5 seconds
// create a Subject which will represent dynamically adding a new stream of form values to the calculation
const formChanges = new Subject<Observable<string>>();
// this will hold the accumulated results
const results: string[] = [];
// subscribe to the subject
// each time any of the inner observables emits a new value, this will log the latest value of all existing inner observables
formChanges.pipe(
mergeMap(innerObs => innerObs, (outerValue, innerValue, outerIndex, innerIndex) => {
results[outerIndex] = innerValue;
return results;
})
).subscribe(console.log);
// emit the known form value change streams
formChanges.next(obsA);
formChanges.next(obsB);
// this will represent adding some other stream of values to the calculation later
formChanges.next(createObs(1750, 'C').pipe(delay(5000))) // after 5 seconds, emit every 1.75 seconds
// Output
// [ 'A: 0' ]
// [ 'A: 1' ]
// [ 'A: 1', 'B: 0' ]
// [ 'A: 2', 'B: 0' ]
// [ 'A: 3', 'B: 0' ]
// [ 'A: 3', 'B: 1' ]
// [ 'A: 4', 'B: 1' ]
// [ 'A: 5', 'B: 1' ]
// [ 'A: 5', 'B: 1', 'C: 0' ]
// [ 'A: 6', 'B: 1', 'C: 0' ]
// [ 'A: 6', 'B: 2', 'C: 0' ]
// [ 'A: 7', 'B: 2', 'C: 0' ]
// [ 'A: 7', 'B: 2', 'C: 1' ]
// [ 'A: 8', 'B: 2', 'C: 1' ]
答案 4 :(得分:-1)
以下是使用TypeScript编写的一种方法:
$args = array('parent' => $category->term_id);
$categories = get_categories( $args );
foreach($categories as $category) {
<a href="<?php echo get_category_link( $category->term_id )?>" title="View posts in <?php echo $category->name?>"><?php $category->name;?></span><!--these are the sub category-->
}