我有表格视图,其中包含我尝试制作 searchBar 并按书名搜索的书籍列表
<块引用>这是 HomeViewModel
- debug:
msg: >-
all hosts in devices are: {{ devices | map("extract", groups) | flatten | list }}
vars:
devices:
- webservers
<块引用>
这个函数绑定到文本值
private var homeModelSubject = PublishSubject<[Book]>()
private var filterModelSubject = PublishSubject<[Book]>()
private var isTableHidden = BehaviorRelay<Bool>(value: false)
var searchValueBehavior = BehaviorRelay<String>(value: "")
var homeModelObservable: Observable<[Book]> {
return homeModelSubject
}
var filterModelObservable: Observable<[Book]> {
return filterModelSubject
}
var isTableHiddenObservable:Observable<Bool> {
return isTableHidden.asObservable()
}
var serchValueObservable: Observable<String> {
return searchValueBehavior.asObservable()
}
init() {
serchValueObservable.subscribe(onNext: { value in
self.homeModelObservable.map({ $0.filter ({
if value.isEmpty {return true}
return ($0.name.lowercased().contains(value.lowercased()))
})
}).bind(to: self.filterModelSubject).disposed(by: self.disposeBag)
}).disposed(by: disposeBag)
}
<块引用>
订阅响应的函数
func bindToSearchValue() {
searchController.searchBar.rx.text.orEmpty.throttle(.milliseconds(500), scheduler: MainScheduler.instance).distinctUntilChanged()
.bind(to: homeViewModel.searchValueBehavior).disposed(by: disposeBage)
}
问题---->make search时没有过滤单元格
答案 0 :(得分:0)
函数式反应式编程的本质是在声明时完全指定值的动态行为。 -- Heinrich Apfelmus
您的视图模型应如下所示:
class HomeViewModel {
let filterModelObservable: Observable<[Book]>
var searchValueObserver: AnyObserver<String?> { searchValueBehavior.asObserver() }
var homeModelObservable: Observable<[Book]> { homeModelSubject }
var isTableHiddenObservable:Observable<Bool> { isTableHidden.asObservable() }
private let homeModelSubject = PublishSubject<[Book]>()
private let isTableHidden = BehaviorRelay<Bool>(value: false)
private let searchValueBehavior = BehaviorSubject<String?>(value: "")
init() {
filterModelObservable = Observable.combineLatest(
searchValueBehavior
.map { $0 ?? "" }
.startWith("")
.throttle(.milliseconds(500), scheduler: MainScheduler.instance),
homeModelSubject
)
.map { searchValue, books in
searchValue.isEmpty ? books : books.filter { $0.name.lowercased().contains(searchValue.lowercased()) }
}
}
}
注意 filterModelObservable
将发出的值是如何在创建它的代码中完全指定的。
您不应该需要这么多主题:
<块引用>Subjects 提供了一种方便的方式来浏览 Rx,但是不建议将它们用于日常使用。 -- Intro to Rx
还要注意,没有 disposeBag。您的视图模型中不应该需要处理包,否则您可能做错了什么。
您应该尽可能减少视图控制器中包含的逻辑。它应该只包含赋值和绑定。因此,您的 bindToSearchBar
应如下所示:
func bindToSearchValue() {
searchController.searchBar.rx.text
.bind(to: homeViewModel.searchValueObserver)
.disposed(by: disposeBage)
}
(您可能还想修正 disposeBage
中的错字。)