Ios 视图模型依赖项注入

Ios 视图模型依赖项注入,ios,mvvm,dependency-injection,viewmodel,rx-swift,Ios,Mvvm,Dependency Injection,Viewmodel,Rx Swift,ItemDetailViewModel使用以下签名初始化: init(item: Item, didPressButton: Observable<Void>, api: FirebaseAPI) init(项:项,按按钮:可观察,api:FirebaseAPI) 它在ItemDetailViewController中初始化,它从源控制器的segue获取一个Item。我意识到ItemDetailViewController在技术上是视图,因此它不应该将项作为存储属性。如何将项目传

ItemDetailViewModel
使用以下签名初始化:

init(item: Item, didPressButton: Observable<Void>, api: FirebaseAPI)
init(项:项,按按钮:可观察,api:FirebaseAPI)
它在
ItemDetailViewController
中初始化,它从源控制器的segue获取一个
Item
。我意识到
ItemDetailViewController
在技术上是
视图
,因此它不应该将
作为存储属性。如何将
项目
传输到
项目详细视图模型
?这也意味着
ItemListViewController
不应在
prepareFor(segue:)
中使用
selectedItem
存储的属性

潜在解决方案

因此,当在
ItemListViewController
(源代码控制器)中点击
CollectionView单元格时,它应该通过绑定到store
Item
触发
ItemListViewModel
,然后执行segue
。同时,在
prepareforsgue
中,我使用
ItemListViewModel
使用
Item
初始化
ItemDetailViewModel
。好啊那可能行得通

如何处理按钮点击,每次点击都会改变其图像?通过函数


初始化
视图模型
注入依赖项
的正确方法是什么

您有一个需要构造三个数据段的对象,但其中一个数据段的来源与其他两个不同。这是使用高阶函数的好时机

struct ItemDetailViewModel {
    static func factory(item: Item, api: FirebaseAPI) -> (_ action: Observable<Void>) -> ItemDetailViewModel {
        return { action in 
            return ItemDetailViewModel(item: item, didPressButton: action, api: api)
        }
    }
}

您的视图模型不应该关注按钮点击。这是视图或视图控制器要处理的。您应该按照建议创建
ItemDetailViewModel
,并通过segue将其传递给
ItemDetailViewController
。当点击按钮时,视图控制器接收到该通知并更新
ItemDetailViewModel
。好的,所以当我订阅按钮点击时,在订阅块内,我将调用viewModel上的方法来处理行为。感谢
didPressButton
observable不是点击按钮。相反,这是“视图模型做某事的原因”,这可能是由于按钮点击造成的,也可能不是。因此,在这个问题中,视图模型与按钮点击无关。最好直接将可观察的按钮传递给视图模型,因为这将删除视图控制器中的逻辑。
class ItemDetailViewController: UIViewController {
    var viewModelFactory: (Observable<Void>) -> ItemDetailViewController = { _ in fatalError("factory called before provided.") }

    override func viewDidLoad() {
        super.viewDidLoad()
        let viewModel = viewModelFactory(myButton.rx.tap.asObservable())
        // bind output to view model
    }
}
if let controller = segue.destinationViewController as? ItemDetailViewController {
    controller.viewModelFactory = ItemDetailViewModel.factory(item: anItem, api: api)
}