从ObservableObject删除对象

时间:2020-02-02 16:04:15

标签: swiftui combine observableobject

两个ViewModels,一个是包含roles的{​​{1}}商店:

skills

一个榜样是:

final class RolesStore: ObservableObject {
  @Published var roles: [Role] = []
.....

另一个struct Role: Codable, Identifiable { let id: String var name: String var skills: [Skill] } ViewModel的存储:

skills

以下内容显示了我想做的事情,从final class SkillStore: ObservableObject { @Published var skills: [Skill] = [] ..... 中删除一项技能(方便),并且还从碰巧拥有{{ 1}}:

remove handy skill

如您所见,删除技能SkillStore不会将其从角色role中删除。 我不确定该怎么做,所以我准备了一个可以从Github克隆的Xcode Playground:https://github.com/imyrvold/roleSkills

必须有一种方法使RoleStore依赖于handy中的技能,否则除了循环浏览所有角色并从具有此功能的所有角色中删除技能之外,没有其他方法技能?

1 个答案:

答案 0 :(得分:0)

当我想起一个类可以用Combine的魔法来订阅另一个类的更改时,我找到了解决方案。因此,如果我可以让RoleStore类订阅SkillStore中的更改,那么RoleStore可以在用户删除技能时更新和删除其角色中的技能。

为此,RolesStore需要引用SkillStore

import SwiftUI
import PlaygroundSupport

var skillStore = SkillStore(skills: MySkills.skills())
var roleStore = RoleStore(roles: MyRoles.roles(), skillStore: skillStore)

struct ModelsView: View {
    @ObservedObject var skillStore: SkillStore
    @ObservedObject var roleStore: RoleStore
....

SkillStore已更新为PassthroughSubject,它将发送已删除的技能(deletedPublisher):

import Foundation
import Combine

public final class SkillStore: ObservableObject {
    @Published public var skills: [Skill] = [] {
        didSet {
            let oldSkills = Set(oldValue)
            let uniqueSet = oldSkills.subtracting(self.skills)
            if let deletedSkill = uniqueSet.first {
                deletedPublisher.send(deletedSkill)
            }
        }
    }
    private var cancellables: Set<AnyCancellable> = []
    let deletedPublisher = PassthroughSubject<Skill, Never>()

    public init(skills: [Skill]) {
        self.skills = skills
    }

    public func delete(skills: [Skill]) {
        for skill in skills {
            if let index = self.skills.firstIndex(where: { $0 == skill }) {
                self.skills.remove(at: index)
            }
        }
    }
}

最后,RoleStore从具有该技能的所有角色中删除已删除的技能:

import Foundation
import Combine
import SwiftUI

public final class RoleStore: ObservableObject {
    @Published public var roles: [Role] = []
    @ObservedObject var skillStore: SkillStore
    private var cancellables: Set<AnyCancellable> = []

    public init(roles: [Role], skillStore: SkillStore) {
        self.roles = roles
        self.skillStore = skillStore
        self.skillStore.deletedPublisher.sink { skill in
            for roleIndex in self.roles.indices {
                let skills = self.roles[roleIndex].skills.filter { $0 != skill }
                self.roles[roleIndex].skills = skills
            }
        }
        .store(in: &cancellables)
    }
}

我已通过更改对Playground进行了更新。