两个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}}:
如您所见,删除技能SkillStore
不会将其从角色role
中删除。
我不确定该怎么做,所以我准备了一个可以从Github克隆的Xcode Playground:https://github.com/imyrvold/roleSkills
必须有一种方法使RoleStore
依赖于handy
中的技能,否则除了循环浏览所有角色并从具有此功能的所有角色中删除技能之外,没有其他方法技能?
答案 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进行了更新。