使用RxJS进行数据验证

时间:2016-12-08 05:10:10

标签: functional-programming rxjs5

我有以下函数验证rangeFrom不优于rangeTo,并且rangeFrom在范围列表中不存在。

如何使用RxJS重写此内容?

const isTagAlreadyExist = (tags, currentTag) => _(tags)
    .filter(x => x.id !== currentTag.id)
    .some(x => _.inRange(currentTag.rangeTo, x.rangeFrom, x.rangeTo))
    .value();

const validateRangeFrom = (tags, currentTag) => {
    const errors = {};

    if (isNumeric(currentTag.rangeFrom)) {    
        if (!_.inRange(currentTag.rangeFrom, 0, currentTag.rangeTo)) {
            errors.rangeFrom = 'FROM_TAG_CANNOT_BE_GREATER_THAN_TO_TAG';
        } else if (isTagAlreadyExist(tags, currentTag)) {
            errors.rangeFrom ='TAG_ALREADY_EXISTS';
        }
    }

    return {
        errors
    };
};

1 个答案:

答案 0 :(得分:1)

问题是:您想要将哪些部分重写为rxjs?这两个纯函数可以从我看到的内容中同步运行,我在这里看不到很多用于rxjs的用例 - 当然你总是可以在rxjs流中使用你的函数:

const validateRangeFrom$ = (tags, currentTag) => {
    return Observable.of(currentTag)
        .map(tag => validateRangeFrom(tags, tag));
}

validateRangeFrom$(myTags, currentTag)
    .subscribe(errors => console.log(errors));

但正如你所看到的,如果你只是将它包装在一个流中,这没有多大意义,有用的反应式编程的本质是,一切都是被动的,而不只是一些小部分,所以对于你的例子,你应该从tags$currentTag$开始作为可观察对象 - 让我们假设你有,然后你可以做类似的事情:

const tags$: Observable<ITag[]>...     // is set somewhere, and emits a new array whenever it is changed
const currentTag$: Observable<ITag>... // is set somewhere and emits the tag whenever a new currentTag is set

const validateRangeFrom$ = Observable
    .combineLatest(tags$, currentTag$, (tags, tag) => ({tags, tag}))
    .map(({tags, tag}) => validateRangeFrom(tags, tag));

validateRangeFrom$.subscribe(errors => console.log(errors));

每当发出新的标签数组或选择/设置新的currentTag时,这将自动触发验证 - 但同样:您的验证方法保持不变 - 即使在反应式编程中您也必须进行验证和逻辑运算在某些时候,反应部分通常只涉及数据流(参见:tags$currentTag$