【发布时间】:2021-09-21 06:56:39
【问题描述】:
在我的代码中,我将 post.id 从视图传递到我的视图模型。为了让我的 cmets 出现,我需要初始化 getComments。以前,在我通过post.id 之前,我只是有init(){getComments(id: "E1m3U1FoeCbOwBGPPq4S")} 这条线。 E1m3U1FoeCbOwBGPPq4S 是一个已经包含 cmets 的文档,因此我可以测试以确保实际加载了 cmets。
现在,由于每个帖子都有一组不同的 cmets,我需要根据用户请求 cmets 的帖子更改 id。为此,就像我说的那样,我正在传递 post.id 并打印它(以确保它实际上已通过)。
在我的代码中,需要 init() 来显示 cmets。由于我的 cmets 的显示方式,初始化 getComments 是一项要求。如果没有 init,cmets 会显示一个 ProgressView 并且无处可去。
我的问题是,我可以更新初始化参数吗?如果我正在初始化getComments(id: "E1m3U1FoeCbOwBGPPq4S"),是否可以将E1m3U1FoeCbOwBGPPq4S 更新为传递的post.id?
我不能只将它设置为getComments(id: post.id),因为默认情况下,没有传递任何 ID,所以我得到 Thread 1: Nil 错误。我想我需要一个在用户单击 cmets 按钮时更新的默认值。
CommentsViewModel.swift
class CommentsViewModel : ObservableObject{
@Published var comments: [CommentsModel] = []
@Published var noComments = false
@Published var newComment = false
@Published var commentTxt = ""
let ref = Firestore.firestore()
let uid = Auth.auth().currentUser!.uid
var post: PostModel? {
didSet{
if let post = self.post {
getComments(id: post.id)
}
}
}
init(){getComments(id: "E1m3U1FoeCbOwBGPPq4S")}
func getComments(id: String) {
print("ID from getComments is: \(id)")
}
CommentsView.swift - 显示 ProgressView 并显示 cmets
@StateObject var commentsData = CommentsViewModel()
if commentsData.comments.isEmpty{
Spacer(minLength: 0)
if commentsData.noComments{
Text("No Comments")
}
else{
Text("Test")
}
Spacer(minLength: 0)
}
else{
ScrollView{
VStack(spacing: 15){
ForEach(commentsData.comments){comment in
CommentsRow(post: post, comment: comment, commentData: commentsData)
}
}
.padding()
.padding(.bottom,55)
}
.onAppear {
commentsData.post = post
}
PostRow.swift - 实际显示 cmets 的按钮
var CommentsData: CommentsViewModel
@State private var showingComments = false
Button(action: {
showingComments = true
commentsData.getComments(id: post.id)
}){
Text("Comments")
}
.transition(.move(edge: .leading))
.sheet(isPresented: self.$showingComments)
{
CommentsView(post: post)
}
编辑:init(){getComments(id: "E1m3U1FoeCbOwBGPPq4S")} 和 if let post = self.post {getComments(id: post.id)} 都在控制台中打印,但 E1m3U1FoeCbOwBGPPq4S 是实际用于显示 cmets 的 ID。
【问题讨论】:
-
你在 PostRow.swift 中的
commentsData上调用getComments,但这是commentsData的不同实例,而不是CommentsView中的实例,对吧?我很确定这可以解释您从一开始就遇到的问题。您需要在CommentsView.swift内部的CommentsViewModel实例上调用getComments-- 现在,您在PostRow拥有的实例上调用它,这不一样. -
这可以解释为什么需要
init的误解,因为init是在CommentsView的版本上唯一 调用的东西。在 Swift 中没有初始化函数这样的事情,所以在init中做某事并没有赋予它特殊的属性。但是,在这种情况下,它可能是唯一真正发生的事情。如果comments.isEmpty是true,则onAppear永远不会被调用。 -
哦,这很有意义。如何从 CommentsViewModel 的实例中调用 getComments?你的回答对我来说很有意义。虽然,我认为 onAppear 被调用了?不完全确定。
-
在
onAppear中调用它,但要确保它会发生在某个实际会被调用的地方。现在,如果comments.isEmpty,它永远不会被调用。您应该能够使用调试器来查看当前的调试器是否被调用,但我不知道它是如何实现的——它看起来像是在else块内。或者,其他简单的调试:使用print语句查看。 -
好吧,我在 ScrollView 的 .onAppear 中添加了打印 - 没有打印任何内容。所以你是对的,它没有被调用。
标签: ios xcode firebase swiftui