简体   繁体   English

"SwiftUI:绑定从环境对象派生的结构的属性"

[英]SwiftUI: Binding on property of struct derived from environment object

I have two structs in my task manager app:我的任务管理器应用程序中有两个结构:

struct Task {
    var identifier: String
    var title: String
    var tags: [String] // Array of tag identifiers
}
struct Tag {
    var identifier: String
    var title: String
}

No, you're not necessarily doing something against best practices.不,您不一定会违反最佳实践。 I think in SwiftUI, the concepts of data model storage and manipulation quickly become more complex than, for example, what Apple tends to show in its demo code.我认为在 SwiftUI 中,数据模型存储和操作的概念很快变得比 Apple 在其演示代码中倾向于展示的概念更加复杂。 With a real app, with a single source of truth, like you seem to be using, you're going to have to come up with some ways to bind the data to your views.对于一个真实的应用程序,具有单一事实来源,就像您似乎正在使用的那样,您将不得不想出一些方法来将数据绑定到您的视图。

One solution is to write Binding<\/code> s with your own get<\/code> and set<\/code> properties that interact with your ObservableObject<\/code> .一种解决方案是使用您自己的get<\/code>和set<\/code>属性编写Binding<\/code> ,这些属性与您的ObservableObject<\/code>交互。 That might look like this, for example:这可能看起来像这样,例如:

struct TaskView : View {
    var taskIdentifier: String // Passed from parent view
    
    @EnvironmentObject private var taskStore: TaskStore
    
    private var taskBinding : Binding<Task> {
        Binding {
            taskStore.tasks[taskIdentifier] ?? .init(identifier: "", title: "", tags: [])
        } set: {
            taskStore.tasks[taskIdentifier] = $0
        }
    }
    
    var body: some View {
        TextField("Task title", text: taskBinding.title)
    }
}

You are correct to model your data with value types and manage lifecycle and side-effects with a reference type.使用值类型对数据建模并使用引用类型管理生命周期和副作用是正确的。 The bit you are missing is that Task doesn't implement the Identifiable<\/code> protocol which enables SwiftUI to keep track of the data in a List<\/code> or ForEach<\/code> .您缺少的一点是 Task 没有实现Identifiable<\/code>协议,该协议使 SwiftUI 能够跟踪List<\/code>或ForEach<\/code>中的数据。 Implement that as follows:实现如下:

struct Task: Identifiable {
    var id: String
    var title: String
    var tags: [String] // Array of tag identifiers
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM