Swift Combine Pipeline 比较草稿模型

Posted

技术标签:

【中文标题】Swift Combine Pipeline 比较草稿模型【英文标题】:Swift Combine Pipeline to compare draft model 【发布时间】:2021-02-25 19:01:47 【问题描述】:

我在 SwiftUI 中有一个 VielModel 来处理我的人物模型。为了能够在视图的编辑器中存储草稿人员,我有两个对象:

@Published var person: Person
@Published var draftPerson: Person

在 UI 中,我只更改 DraftPerson,直到用户单击“保存”,这会将 DraftPerson 存储为人员。在编辑器的 onAppear 方法中,我将 draftPerson 重置为 person。

现在我想禁用编辑器的“保存”按钮,因此在 VM 中引入了一个布尔“修改”。使用管道,如果并且只要 DraftPerson 不等于 person,我想通过执行以下操作将 modified 设置为 true:

    $draftPerson.map  draftPerson in
        return draftPerson != self.person
    
    .assign(to: \.modified, on: self)
    .store(in: &cancellables)

乍一看它似乎正在工作,但如果我在 textField 中更改某些内容,modified 的值仅在该字段的第二次更改后设置为 true。反之亦然,如果我删除键入的值,则只有在我删除原来存在的一个字符后才将其设置回 false。

问题 1: 是否有另一种“最佳实践”来处理草稿对象的更改并停用 SwiftUI 中的“保存”按钮?

问题 2: 为什么管道“落后一变”?

非常感谢您的意见。

编辑:我创建了应用程序的一个单独部分,仅关注管道,并意识到如果我删除其他管道,它确实可以按预期工作。我现在必须详细检查。不过,我会坚持我的第一个问题: 有什么我可以做得更好的吗?

请查找代码here on Github

【问题讨论】:

这看起来很清楚。我认为目标是(或多或少)如果它们相同则禁用保存,如果它们不同则启用保存,因为用户更改了草稿人员文本字段的值,是吗?文本字段如何“挂钩”到draftPerson 没错,感谢您的回复。 Textfeld 绑定到结构“Person”中的 var“name”。视图中的代码是: TextField("Name", text: $personViewModel.draftPerson.name) 你能展示视图模型如何适应实际视图吗?它是如何举行的?如果您显示您的代码而不是谈论关于它,那真的会有所帮助。 非常感谢@matt,我相应地更改了最初的问题。它现在似乎在简化版本中工作,所以如果您想在我的代码中指出任何其他内容,请随时这样做。 【参考方案1】:

您可以声明另一个@Published 属性并结合两个person 和draftPerson 发布者并发布它们是否相同,如下所示:

@Published var person: Person
@Published var draftPerson: Person
@Published var saveDisabled: Bool = true

public init() 
    
    // all init code
    
    Publishers.CombineLatest($person, $draftPerson)
        .map  $0 == $1 
        .assign(to: &$saveDisabled)
    

但本质上它是不需要的,计算属性会做同样的工作:

var saveDisabled: Bool 
    person == draftPerson

因为 person 和 draftPerson 每次都被标记为 @Published,所以 View 将收到更改通知,因此它也会选择 saveDisabled 的新值。

【讨论】:

非常感谢。这正是我所做的(抱歉没有在我的初始帖子中添加该属性),但您可以在此处查看代码:gist.github.com/brenner-tobias/0dcf340342e9142d8538458c5d945e9f 使用计算变量的想法/简化很好,我会尝试一下

以上是关于Swift Combine Pipeline 比较草稿模型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Combine + Swift 复制 PromiseKit 风格的链式异步流

使用 Swift 和 Combine 链接 + 压缩多个网络请求

Xcode 11 中 Swift Combine.framework 的可选链接

Swift/Combine - 将过滤后的对象分配给类的属性

Swift Combine:没有“distinct”运算符?

Swift Combine - @Published 属性数组