如何将模型数据从 ViewController 传递到 ViewModel
How to pass Model data from ViewController to ViewModel
我正在修改我的应用程序以实现 MVVM
模式。
简介:
我使用 WebServices
来获取我所有的数据。
在应用程序启动时,在加载屏幕期间,我向所有 Web 服务发出请求,以便我的所有数据都可用。
例如,当我点击应用程序中的菜单以访问特定场景时,我已经拥有了所有需要的数据,我将模型传递给相应的 ViewController 和 Segue
.
问题:
真正的问题是,将此模型数据传递给我的 ViewModel
的好方法是什么?
我正在使用实现 Codable
协议的结构在请求 Web 服务并解析 json 数据后获取我的模型。
这是我的 ViewController 的样子:
class VigilanceViewController: UIViewController {
@IBOutlet var outletTableView: UITableView!
var vigilance: Vigilance?
fileprivate let viewModel = VigilanceViewModel()
override func viewDidLoad() {
super.viewDidLoad()
if let vigilance = vigilance {
// pass data to the viewModel
}
outletTableView.dataSource = viewModel
}
}
在 ViewModel 中,我不知道如何声明 Vigilance 模型或如何正确初始化 ViewModel。
这是视图模型:
class VigilanceViewModel: NSObject {
var items = [VigilanceViewModelItem]()
var maxVigilance: Int = 0
var vigilance: Vigilance? = nil
override init() {
super.init()
// Append objects in my items array from the vigilance Model so that the dataSource is ready to go and clean
}
}
extension VigilanceViewModel: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return maxVigilance - 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].rowCount
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
// TODO
return cell
}
}
因为我的模型包含很多我目前不需要的信息 ViewController,我正在制作一个项目数组,以便在我的 DataSource
中更容易使用。
这是我的警戒模型的样子:
struct Vigilance: Codable {
let result: Result
struct Result: Codable {
let startDate: Int
let endDate: Int
let sendDate: Int
let advice: String?
let comment: String?
let colorMax: Int
let details: [VigilanceDetails]?
struct VigilanceDetails: Codable {
let dptNumber: String
let dptName: String
let color: String
let risks: [Risks]?
struct Risks: Codable {
let code: String
let label: String
}
}
}
}
我的第一个猜测是为什么我不能在没有可选的情况下声明我的模型是因为我没有正确的自定义初始化程序?
但这不是这里的主要问题。
我想知道如何将这个模型数据(之前在这个VC中从prepareForSegue
获得)传递给ViewModel,并正确初始化ViewModel。
如果有人能在这里指导我,我将不胜感激。
我正在探索 OS 和设计模式中一些晦涩的部分,尽我最大的努力去理解和应用我所学的东西。
My first guess on why I can't declare my model without optional is
because I don't have custom initializer right ?
只要您使用 segues 启动您的 UIViewControllers,您就不能使用自定义初始化器,您可以在其中传递所需的对象。
如果你想避免可选变量,我建议写一个 init 函数,像这样(并将你的 VC 移动到 xib 文件):
class ViewController: UIViewController {
let param: String
init(param: String) {
self.param = param
super.init(nibName: "YourViewControllerNibsName", bundle: Bundle.main)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The real question is, what is a good way to pass this model data to my ViewModel?
一旦你从代码而不是 segues 启动你的视图控制器,你就可以写一些辅助函数,通常我把它放在路由器中(或者你喜欢的名字)class,比如:
class AppRouter {
// Return UIViewController not to expose the type of ViewController
static func getViewController(with param: String) -> UIViewController {
return ViewController(param: param)
}
}
// Using it from an another VC
let actualVC: UIViewController!
let vcToPresent = AppRouter.getViewController(with: "yourParam")
actualVC.present(vcToPresent, animated: true, completion: nil)
And what about the same declaration but in the ViewModel?
class VigilanceViewModel: NSObject {
let items: [VigilanceViewModelItem]
let maxVigilance: Int
let vigilance: Vigilance
init(items: [VigilanceViewModelItem], vigilance: Vigilance) {
self.items = items
self.vigilance = vigilance
maxVigilance = vigilance.max
}
}
我正在修改我的应用程序以实现 MVVM
模式。
简介:
我使用 WebServices
来获取我所有的数据。
在应用程序启动时,在加载屏幕期间,我向所有 Web 服务发出请求,以便我的所有数据都可用。
例如,当我点击应用程序中的菜单以访问特定场景时,我已经拥有了所有需要的数据,我将模型传递给相应的 ViewController 和 Segue
.
问题:
真正的问题是,将此模型数据传递给我的 ViewModel
的好方法是什么?
我正在使用实现 Codable
协议的结构在请求 Web 服务并解析 json 数据后获取我的模型。
这是我的 ViewController 的样子:
class VigilanceViewController: UIViewController {
@IBOutlet var outletTableView: UITableView!
var vigilance: Vigilance?
fileprivate let viewModel = VigilanceViewModel()
override func viewDidLoad() {
super.viewDidLoad()
if let vigilance = vigilance {
// pass data to the viewModel
}
outletTableView.dataSource = viewModel
}
}
在 ViewModel 中,我不知道如何声明 Vigilance 模型或如何正确初始化 ViewModel。
这是视图模型:
class VigilanceViewModel: NSObject {
var items = [VigilanceViewModelItem]()
var maxVigilance: Int = 0
var vigilance: Vigilance? = nil
override init() {
super.init()
// Append objects in my items array from the vigilance Model so that the dataSource is ready to go and clean
}
}
extension VigilanceViewModel: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return maxVigilance - 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].rowCount
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
// TODO
return cell
}
}
因为我的模型包含很多我目前不需要的信息 ViewController,我正在制作一个项目数组,以便在我的 DataSource
中更容易使用。
这是我的警戒模型的样子:
struct Vigilance: Codable {
let result: Result
struct Result: Codable {
let startDate: Int
let endDate: Int
let sendDate: Int
let advice: String?
let comment: String?
let colorMax: Int
let details: [VigilanceDetails]?
struct VigilanceDetails: Codable {
let dptNumber: String
let dptName: String
let color: String
let risks: [Risks]?
struct Risks: Codable {
let code: String
let label: String
}
}
}
}
我的第一个猜测是为什么我不能在没有可选的情况下声明我的模型是因为我没有正确的自定义初始化程序?
但这不是这里的主要问题。
我想知道如何将这个模型数据(之前在这个VC中从prepareForSegue
获得)传递给ViewModel,并正确初始化ViewModel。
如果有人能在这里指导我,我将不胜感激。
我正在探索 OS 和设计模式中一些晦涩的部分,尽我最大的努力去理解和应用我所学的东西。
My first guess on why I can't declare my model without optional is because I don't have custom initializer right ?
只要您使用 segues 启动您的 UIViewControllers,您就不能使用自定义初始化器,您可以在其中传递所需的对象。 如果你想避免可选变量,我建议写一个 init 函数,像这样(并将你的 VC 移动到 xib 文件):
class ViewController: UIViewController {
let param: String
init(param: String) {
self.param = param
super.init(nibName: "YourViewControllerNibsName", bundle: Bundle.main)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
The real question is, what is a good way to pass this model data to my ViewModel?
一旦你从代码而不是 segues 启动你的视图控制器,你就可以写一些辅助函数,通常我把它放在路由器中(或者你喜欢的名字)class,比如:
class AppRouter {
// Return UIViewController not to expose the type of ViewController
static func getViewController(with param: String) -> UIViewController {
return ViewController(param: param)
}
}
// Using it from an another VC
let actualVC: UIViewController!
let vcToPresent = AppRouter.getViewController(with: "yourParam")
actualVC.present(vcToPresent, animated: true, completion: nil)
And what about the same declaration but in the ViewModel?
class VigilanceViewModel: NSObject {
let items: [VigilanceViewModelItem]
let maxVigilance: Int
let vigilance: Vigilance
init(items: [VigilanceViewModelItem], vigilance: Vigilance) {
self.items = items
self.vigilance = vigilance
maxVigilance = vigilance.max
}
}