当我运行代码时,我在视图Model中发布的变量被重置为它们的缺省值

omqzjyyz  于 2022-09-19  发布在  Swift
关注(0)|答案(1)|浏览(104)

我在更新模型中发布的变量时遇到了问题,所以我尝试用一组非常基本和简单的文件/代码来复制这个问题。所以基本上在NavLink view中,有一个导航链接,当点击它时,它会更新ListRepository model中发布的变量,给它一个字符串值“yes”,打印到控制台,然后导航到它的目的地,称为ContentView view。问题出在ContentView中,我试图打印包含在名为selectedFolderId的已发布变量中的数据,希望它会打印“yes”,但我注意到,它没有打印NavLink view中设置的值,而是打印""的默认值,这不是NavLink view中设置的值。请大家解释一下出现这种行为的原因,并向我解释一下如何解决这个问题,因为我对快速用户界面非常陌生。这将意味着很多。

请在下面找到支持文件:

import SwiftUI

struct NavLink: View {

    @StateObject var listRepository = ListRepository()

    var body: some View {

        NavigationView{
            ScrollView {

                NavigationLink("Hello world", destination: ContentView(listRepository: listRepository))

                Text("Player 1")
                Text("Player 2")
                Text("Player 3")
            }
            .simultaneousGesture(TapGesture().onEnded{
                listRepository.selectedFolderId = "yes"
                listRepository.md()
            })
            .navigationTitle("Players")
        }
    }
}

struct NavLink_Previews: PreviewProvider {
    static var previews: some View {
        NavLink()
    }
}
import Foundation

class ListRepository: ObservableObject {

    @Published var selectedFolderId = ""

    func md(){
        print("=====")
        print(self.selectedFolderId)
        print("======")
    }
}
import SwiftUI

struct ContentView: View {

    @ObservedObject var taskListVM = ShoppingListItemsViewModel()
    @ObservedObject var listRepository:ListRepository

    var body: some View {
        VStack{
            Text("content 1")
            Text("content 2")
            Text("content 3")
        }
        .onAppear{
            taskListVM.addTask()
            print("========")
            print(listRepository.selectedFolderId)
            print("========")

        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
class ShoppingListItemsViewModel: ObservableObject {

    @Published var listRepository = ListRepository()

    @Published var taskCellViewModels = [ShoppingListItemCellViewModel]()

    private var cancellables = Set<AnyCancellable>()

    init() {

        listRepository.$tasks
            .map { lists in
                lists.map { list in
                    ShoppingListItemCellViewModel(task: list)
                }
            }
            .assign(to: \.taskCellViewModels, on: self)
            .store(in: &cancellables)
    }

    func addTask() {
        listRepository.addTask(task)
    }
}
kulphzqa

kulphzqa1#

当您第一次处理应用程序中的数据流时,这是一个常见问题。问题很简单。在‘NavLink’视图中,您正在创建ListRepository的一个版本,而在ContentView中,您将创建另一个不同版本的ListRepository。您需要做的是在调用NavLink时将在NavLink中创建的ListRepository传递给ContentView。下面是一个如何做到这一点的例子:

struct NavLink: View {

    @StateObject var listRepository = ListRepository() // Create as StateObject, not ObservedObject

    var body: some View {

        NavigationView{
            ScrollView {

                NavigationLink("Hello world", destination: ContentView(listRepository: listRepository)) // Pass it here

                Text("Player 1")
                Text("Player 2")
                Text("Player 3")
            }
            .simultaneousGesture(TapGesture().onEnded{
                listRepository.selectedFolderId = "yes"
                listRepository.md()
            })
            .navigationTitle("Players")
        }
    }
}

struct ContentView: View {

    @ObservedObject var listRepository: ListRepository // Do not create it here, just receive it

    var body: some View {
        VStack{
            Text("content 1")
            Text("content 2")
            Text("content 3")
        }
        .onAppear{
            print("========")
            print(listRepository.selectedFolderId)
            print("========")

        }
    }
}

您还应该注意到,我将ListRepository创建为StateObject。最初创建ObservableObject的视图必须将其创建为StateObject,否则可能会产生不良副作用。

相关问题