SwiftUI - MVVM之ViewModel
2021-02-19 15:20
标签:span post 苹果公司 where int override fetch sel 更新 什么是ViewModal ViewModal是View和数据的中间层。ViewModel是视图和数据之间的一层。 ViewModel通常使用service objects来获取数据,对其进行格式化后向View提供格式化的数据。 苹果什么时候开始推动MVVM 当苹果将ObservableObject协议移至Combine框架时,苹果公司开始推广MVVM模式。让我们看一下ObservableObject协议,以了解发生了什么。 ObservableObject协议具有唯一的要求,即在对象更改之前发出的发布者。让我们编写第一个符合ObservableObject协议的ViewModel。 在这里,我们有ViewModel来获取帖子,将它们存储在变量中,并通过objectWillChange发布者发出通知。让我们看一下使用此ViewModel的示例ViewController。 如您在上面的示例中看到的,我们有PostsViewController,它开始观察ViewModel中的更改,然后要求ViewModel提取数据。一旦ViewModel提取数据,它就会发出,并且ViewController调用renderPosts函数,该函数显示下载的帖子。 Published property wrapper 我们可以使用@Published属性包装器进行进一步操作。 @Published属性包装器允许我们将发布者包装任何属性,只要属性更改,发布者就会发出当前值。 正如您在上面的示例中看到的那样,我们不需要手动将值发送给objectWillChange发布者,这是Swift编译器合成的所有工作。并且我们可以保持PostsViewController的相同实现。 如前所述,@ Published属性包装器将我们的属性与发布者包装在一起。让我们看看如何在PostsViewController中使用它 在这里,我们有一个PostsViewController的重构版本。请看一下我们如何更改bindViewModel函数。它现在订阅$ posts,并且仅当特定属性更改时,它才允许我们更新视图 SwiftUI - MVVM之ViewModel 标签:span post 苹果公司 where int override fetch sel 更新 原文地址:https://www.cnblogs.com/liuxiaokun/p/12684399.htmlSwiftUI - MVVM之ViewModel
/// A type of object with a publisher that emits before the object has changed.
public protocol ObservableObject : AnyObject {
/// The type of publisher that emits before the object has changed.
associatedtype ObjectWillChangePublisher : Publisher = ObservableObjectPublisher where Self.ObjectWillChangePublisher.Failure == Never
/// A publisher that emits before the object has changed.
var objectWillChange: Self.ObjectWillChangePublisher { get }
}
final class PostsViewModel: ObservableObject {
let objectWillChange = PassthroughSubject
final class PostsViewController: UIViewController {
let viewModel: PostsViewModel
override func viewDidLoad() {
super.viewDidLoad()
bindViewModel()
viewModel.fetch()
}
private func bindViewModel() {
viewModel.objectWillChange.sink { [weak self] in
guard let self = self else {
return
}
self.renderPosts(self.viewModel.posts)
}
}
}
final class PostsViewModel: ObservableObject {
@Published private(set) var posts: [Post] = []
func fetch() {
// fetch posts and assign them to `posts` variable
}
}
final class PostsViewController: UIViewController {
let viewModel: PostsViewModel
override func viewDidLoad() {
super.viewDidLoad()
bindViewModel()
viewModel.fetch()
}
private func bindViewModel() {
viewModel.$posts.sink { [weak self] posts in
self?.renderPosts(posts)
}
}
}