使用 RxJS 进行数据验证
Data validation using RxJS
我有以下函数验证 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
};
};
问题是:你想把哪些部分重写成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 是 selected/set 时,这将自动为您触发验证 - 但同样:您的验证方法保持不变 - 即使在反应式编程中必须在某些时候进行验证和逻辑操作,反应部分通常只关注数据流(参见:tags$
和 currentTag$
)
我有以下函数验证 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
};
};
问题是:你想把哪些部分重写成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 是 selected/set 时,这将自动为您触发验证 - 但同样:您的验证方法保持不变 - 即使在反应式编程中必须在某些时候进行验证和逻辑操作,反应部分通常只关注数据流(参见:tags$
和 currentTag$
)