如何在RX(Swift)中以自然样式的序列和条件接近组合



我有3个序列可以找出是否需要保存更改文本文件:

  1. 文本ID (显示另一个文本时更改;其存在也表示"这是注释"(
  2. (
  3. 文本编辑状态更改(可以说,作为守卫条件,以确保用户真正编辑,而不仅仅是查看文本(
  4. 内容更改(当用户键入文本字段时(

产生元素的顺序是由此产生的组合。上面的列表代表快乐路径。

rxswift/rxtest测试用例:

func testContentThenEditingThenChange_ProducesEdit() {
    let identifier = scheduler.createHotObservable([next(300, "identifier")])
    let isEditing = scheduler.createHotObservable([next(400, true)])
    let changedText = scheduler.createHotObservable([next(500, "foo")])
    let viewModel = TextEditingViewModel(
        identifier: identifer.asObservable(),
        changedText: changedText.asObservable(),
        isEditing: isEditing.asObservable())
    let result = scheduler.start { viewModel.textChange }
    XCTAssertEqual(result.events, [next(500, TextChange(identifier: "identifier", text: "foo"))])
}

您将如何编写并保持高可读性?

我可以提出2个变体,我不喜欢这两个变体。

flatmap自然顺序的3个序列

,这是一个确实有效的实现。

struct TextEditingViewModel {
    let identifier: Observable<Identifier>
    let changedText: Observable<String>
    let isEditing: Observable<Bool>
    var textChange: Observable<TextChange> {
        return identifier
            .flatMap { identifier in self.isEditing.filter { $0 == true }.map { _ in identifier } }
            .flatMap { identifier in self.changedText.map { text in (identifier, text) } }
            .map { identifier, text in TextChange(identifier: identifier, text: text) }
    }
}

平面映射并将外部序列的价值放入组合中是一种非常回旋的方法。我仅根据测试才能发现该解决方案。我最初的方法是使用withLatestFrom,主要是因为所产生的代码读取的读物就像我想告诉的故事一样:

withlatest从yoda style

自然顺序,这不会产生预期的结果:

// Does not work!
var textChange: Observable<TextChange> {
    return identifier
        .withLatestFrom(isEditing.filter { $0 == true }) { identifier, _ in identifier }
        .withLatestFrom(identifier) { _, identifier in identifier }
        .withLatestFrom(changedText) { identifier, text in (identifier, text) }
        .map { identifier, text in TextChange(identifier: identifier, text: text) }
}

如果我坚持使用withLatestFrom,因为它比flatMap更有意图,则我必须在Yoda式的情况下写下序列组合,也就是说:向后。

var textChange: Observable<TextChange> {
    return changedText
        .withLatestFrom(isEditing.filter { $0 == true }) { text, _ in text }
        .withLatestFrom(identifier) { text, identifier in (identifier, text) }
        .map { identifier, text in Edit(identifier: identifier, text: text) }
}

因此,不是"自然"的情况:"当您有标识符并正在编辑时,然后进行文本更改,产生元素",我从结尾处讲故事,"当文本更改出现时,如果您正在编辑,如果您有标识符,则产生一个元素"。

相关内容

  • 没有找到相关文章

最新更新