0

ViewModels,一个是roles包含的存储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] = []
.....

下面显示了我想要做什么,从SkillStore(handy)中删除一项技能,并自动从任何role碰巧拥有该技能的技能中删除已删除的技能RoleStore

删除方便的技能

如您所见,移除技能handy并不会将其从角色中移除Ansatt。我不知道该怎么做,所以我准备了一个任何人都可以从 Github 克隆的 Xcode Playground:https ://github.com/imyrvold/roleSkills

必须SkillStore有一种依赖于技能的方法,SkillStore或者除了循环遍历所有角色并从所有具有该技能的角色中删除该技能之外,没有其他方法吗?

4

1 回答 1

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。

于 2020-02-09T10:14:02.747 回答