具有输入输出的 rxswift viewmodel
rxswift viewmodel with input output
我正在尝试在 RxSwift repo 的 rxswift 示例项目中实现类似的东西。但就我而言,有依赖的可观察量。如果不在 viewmodel
中使用绑定,我找不到任何解决方案
这是我的视图模型的结构:
首先是输入、输出和viewmodel的定义
typealias UserListViewModelInput = (
viewAppearAction: Observable<Void>,
deleteAction: Observable<Int>
)
typealias UserListViewModelOutput = Driver<[User]>
typealias UserListViewModel = (UserListViewModelInput, @escaping UserApi) -> UserListViewModelOutput
然后是无法编译的实际实现。
let userListViewModel: UserListViewModel = { input, loadUsers in
let loadedUserList = input.viewAppearAction
.flatMapLatest { loadUsers().materialize() }
.elements()
.asDriver(onErrorDriveWith: .never())
let userListAfterDelete = input.deleteAction
.withLatestFrom(userList) { index, users in
users.enumerated().compactMap { [=11=].offset != index ? [=11=].element : nil }
}
.asDriver(onErrorJustReturn: [])
let userList = Driver.merge([loadedUserList, userListAfterDelete])
return userList
}
Viewmodel 有两个工作。首先加载用户列表。其次是删除索引处的用户。最终输出是下载的用户列表,其中 UserApi
减去已删除的用户。
这里的问题为了定义userList
我需要定义userListAfterDelete
。为了定义 userListAfterDelete
我需要定义 userList
.
那么有没有办法在不使用视图模型内部绑定的情况下打破这个循环?就像保持状态的占位符 observable 或运算符?
这是状态机的工作。您将在下面的代码中看到有两个操作可以影响 User 数组。当视图出现时,将下载一个新数组,当出现删除时,将删除特定用户。
这可能是处理状态的反应式代码中最常见的模式。如此普遍以至于有整个库实现了它的一些变体。
let userListViewModel: UserListViewModel = { input, loadUsers in
enum Action {
case reset([User])
case delete(at: Int)
}
let resetUsers = input.viewAppearAction
.flatMapLatest { loadUsers().materialize() }
.compactMap { [=10=].element }
.map { Action.reset([=10=]) }
let delete = input.deleteAction.map { Action.delete(at: [=10=]) }
return Observable.merge(resetUsers, delete)
.scan(into: [User](), accumulator: { users, action in
switch action {
case let .reset(newUsers):
users = newUsers
case let .delete(index):
users.remove(at: index)
}
})
.asDriver(onErrorJustReturn: [])
}
我正在尝试在 RxSwift repo 的 rxswift 示例项目中实现类似的东西。但就我而言,有依赖的可观察量。如果不在 viewmodel
中使用绑定,我找不到任何解决方案这是我的视图模型的结构:
首先是输入、输出和viewmodel的定义
typealias UserListViewModelInput = (
viewAppearAction: Observable<Void>,
deleteAction: Observable<Int>
)
typealias UserListViewModelOutput = Driver<[User]>
typealias UserListViewModel = (UserListViewModelInput, @escaping UserApi) -> UserListViewModelOutput
然后是无法编译的实际实现。
let userListViewModel: UserListViewModel = { input, loadUsers in
let loadedUserList = input.viewAppearAction
.flatMapLatest { loadUsers().materialize() }
.elements()
.asDriver(onErrorDriveWith: .never())
let userListAfterDelete = input.deleteAction
.withLatestFrom(userList) { index, users in
users.enumerated().compactMap { [=11=].offset != index ? [=11=].element : nil }
}
.asDriver(onErrorJustReturn: [])
let userList = Driver.merge([loadedUserList, userListAfterDelete])
return userList
}
Viewmodel 有两个工作。首先加载用户列表。其次是删除索引处的用户。最终输出是下载的用户列表,其中 UserApi
减去已删除的用户。
这里的问题为了定义userList
我需要定义userListAfterDelete
。为了定义 userListAfterDelete
我需要定义 userList
.
那么有没有办法在不使用视图模型内部绑定的情况下打破这个循环?就像保持状态的占位符 observable 或运算符?
这是状态机的工作。您将在下面的代码中看到有两个操作可以影响 User 数组。当视图出现时,将下载一个新数组,当出现删除时,将删除特定用户。
这可能是处理状态的反应式代码中最常见的模式。如此普遍以至于有整个库实现了它的一些变体。
let userListViewModel: UserListViewModel = { input, loadUsers in
enum Action {
case reset([User])
case delete(at: Int)
}
let resetUsers = input.viewAppearAction
.flatMapLatest { loadUsers().materialize() }
.compactMap { [=10=].element }
.map { Action.reset([=10=]) }
let delete = input.deleteAction.map { Action.delete(at: [=10=]) }
return Observable.merge(resetUsers, delete)
.scan(into: [User](), accumulator: { users, action in
switch action {
case let .reset(newUsers):
users = newUsers
case let .delete(index):
users.remove(at: index)
}
})
.asDriver(onErrorJustReturn: [])
}