MVVM 将数据从视图传递到另一个视图的 viewModel
我是 MVVM 新手,我正在尝试将位置数据从我的 ContenView 传递到 DetailsView 的 viewModel,即 DetailsViewViewModel。
我的打开视图 -> ContentView(我的数据在这里)
第二个视图 ->详情查看
数据必须到达-> DetailsViewViewModel
这是我在 ContentView 中的工作表,
.sheet(item: $viewModel.selectedPlace) { place in
DetailsView(location: place) { newLocation in
viewModel.updateLocation(location: newLocation)
}
我知道我正在尝试将数据发送到详细信息视图,但这是错误的。在我将架构转换为 MVVM 之前就像这样,这是我唯一无法转换的地方。 这也是我的DetailsViewViewModel
extension DetailsView {
@MainActor class DetailsViewViewModel: ObservableObject {
enum LoadingState {
case loading, loaded, failed
}
var location: Location
@Published var name: String
@Published var description: String
@Published var loadingState = LoadingState.loading
@Published var pages = [Page]()
init() {
self.location = // ??? how should i initialize?
self.name = location.name
self.description = location.description
}
正确的方法是什么。在另一个视图视图模型中使用另一个视图数据。
I'm new to MVVM and i am trying to pass a location data from my ContenView to DetailsView's viewModel which is DetailsViewViewModel.
My Opening View -> ContentView (My data is here)
Second View -> DetailsView
Data must be reach -> DetailsViewViewModel
Here is my sheet in ContentView
.sheet(item: $viewModel.selectedPlace) { place in
DetailsView(location: place) { newLocation in
viewModel.updateLocation(location: newLocation)
}
I know i'm trying to send my data to details view and it's wrong. It was like that before i convert the architecture to the MVVM and this is the only place that i couldn't convert.
Also here is my DetailsViewViewModel
extension DetailsView {
@MainActor class DetailsViewViewModel: ObservableObject {
enum LoadingState {
case loading, loaded, failed
}
var location: Location
@Published var name: String
@Published var description: String
@Published var loadingState = LoadingState.loading
@Published var pages = [Page]()
init() {
self.location = // ??? how should i initialize?
self.name = location.name
self.description = location.description
}
What is the proper way to this. Using another views data in another views viewmodel.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
让我尝试举一个使用
@EnvironmentObject
便利性的示例:您的视图模型是一个符合
ObservableObject
的类,因此您可以拥有那些不错的改变视图状态的变量@Published
。您的主视图 - 或者您的
App
- 必须“拥有”视图模型,这意味着它需要创建将由所有视图使用的视图模型的唯一实例。< /p>您可以使用 @StateObject 和 @ObservableObject 将视图模型从一个视图传递到另一个视图,但在本例中我更喜欢使用另一种方法。让您的主视图在环境中注入视图模型的实例,以便所有其他视图都将从中读取。主视图使用
.environmentObject(viewModel)
来执行此操作。其他视图通过调用@EnvironmentObject从环境中读取视图模型。他们创建一个仅指定类型的变量 - 环境中每种类型只能有一个实例。
这是所有视图从同一模型读取的方式。请参阅下面的功能示例:
步骤 1:
步骤 2 和步骤 3:
步骤 4 在两个不同的视图中:
Let me try to put in an example that uses the convenience of
@EnvironmentObject
:Your view model is a class that conforms to
ObservableObject
, so you can have those nice variables@Published
that change the state of the views.Your main view - or also your
App
- must "own" the view model, meaning it needs to create the one and only instance of your view model that will be used by all views.You pass the view model from one view to another using
@StateObject
and@ObservableObject
, but in this example I prefer to use another approach. Make your main view inject the instance of your view model in the environment, so all other views will read from that. The main view uses.environmentObject(viewModel)
to do that.The other views read the view model from the environment by calling
@EnvironmentObject
. They create a variable specifying only the type - there can only be one instance per type in the environment.This is the way with which all view will read from the same model. See below a functioning example:
Step 1:
Steps 2 and 3:
Step 4 in two different views:
由于位置数据是您的业务层数据,因此您需要一个用例将其提供给两个视图模型,并且要优化它,缓存响应是可行的方法。
-ViewModel 负责保存最新的视图状态和数据
-领域层负责处理业务逻辑
-数据层(网络、缓存、持久化或内存)负责提供最高效的数据存储/检索解决方案
因此,如果您接受这些定义并考虑为这些视图模型编写测试,您就会知道从另一个 ViewModel 注入数据是不正确的,因为您不会测试该视图模型以确保它将数据传递到下一个 viewModel这不是它的责任,但是您为数据层编写了许多测试,以确保服务调用和缓存系统正常工作。
since location data is your business layer data, you need a use-case to provide it to both view models, and to optimize it caching the response is the way to go.
-ViewModel is responsible to hold the latest view states and data
-The domain layer is responsible to handle business logic
-The data layer (networking, cache, persistence, or in-memory) is responsible for providing the most efficient data storage/retrieval solutions
So, if you are okay with these defenitions and think of writing test for these view models you know that it is not right to inject data from another ViewModel because you would not test that view model on making sure it passes the data to the next viewModel and it is not its responsibility, but you write many tests for you data layer to make sure service calls and caching systems are working properly.
当您添加DetailsView时,您需要从ContentView表初始化DetailsViewModel,如下所示:
ContentView
DetailsView:
DetailsViewModel:
You need to initialise DetailsViewModel from ContentView sheet when you are adding the DetailsView like below:
ContentView
DetailsView:
DetailsViewModel: