我正在使用 ReactiveCocoa 并尝试应用 MVVM。我有一个相当典型的 UITableView 场景,带有用于重新加载数据的刷新控件。
我省略了 UITableDataSource/Delegate 方法,因为这些方法很简单。下面的代码说明了我是如何设计 ViewModel 和 ViewController 以配合在一起的。
ViewModel.h
@property (strong, nonatomic, readonly) RACCommand *getItemsCommand;
@property (strong, nonatomic, readonly) NSArray *items;
ViewModel.m
- (instancetype)init {
self = [super init];
if (!self) return nil;
@weakify(self);
self.getItemsCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
return [[ItemsDataSource getItems]
doNext:^(NSArray *items) {
@strongify(self);
// I actually do a little extra work here such as sorting
// the items appropriately for the view.
self.items = items;
}];
}];
return self;
}
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView addSubview:self.refreshControl];
RACSignal *refreshSignals = [RACSignal merge:@[
[self.refreshControl rac_signalForControlEvents:UIControlEventValueChanged],
[RACSignal return:nil]
]];
[refreshSignals
subscribeNext:^(id x) {
[self.viewModel.getItemsCommand execute:nil];
}];
[RACObserve(self.viewModel, items)
subscribeNext:^(NSArray *items) {
[self.tableView reloadData];
} completed:^{
[self.refreshControl endRefreshing];
}];
}
问题/问题
completed
我打电话的地方endRefreshing
永远不会被处决,对于我的一生,我无法弄清楚为什么。 - (RACSignal *)getItems
而不是 getItems
RAC 命令? doNext:
在 ViewModel 中正确以应用副作用(即项目数组的排序)而不导致额外订阅? 最佳答案
我建议制作 getItemsCommand
使用 -map:
对项目数组进行排序和处理。将任何其他副作用工作留在单独的 -doNext:
中完成.一旦您的命令遵循此模式(在 RAC 中更具组合性),您就可以使用 RAC()
宏将命令的成品,排序后的数组,分配给 items
属性(property)。
RAC(self, items) = [self.getItemsCommand.executionSignals concat];
RAC 具有对
UIRefreshControl
的内置命令支持。这将启动/停止刷新控制以及命令的启动/停止。你应该发现你可以减少你的UIRefreshControl
代码:self.refreshControl.rac_command = self.getItemsCommand;
对于表重新加载,您可以执行以下操作:
[RACObserve(self, items) subscribeNext:^(id _) {
@strongify(self);
[self.tableView reloadData];
}];
希望有帮助。
关于objective-c - 带有 UITableView 的 ReactiveCocoa MVVM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23203436/