Swift 组合管道来比较草稿模型

问题描述 投票:0回答:1

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

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

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

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

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

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

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

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

非常感谢您的投入。

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

请在 Github 上找到代码

swift swiftui combine
1个回答
0
投票

您可以声明另一个

@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 的新值。

© www.soinside.com 2019 - 2024. All rights reserved.