组合信号,但只在第一个更改时订阅

时间:2013-12-18 15:26:01

标签: ios objective-c reactive-cocoa

我想将UIButton上的rac_signalForControlEvent与一些组合的textFields信号结合起来:

    [[[[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside]
    combineLatestWith:textFieldsCombinedSignal]
    filter:^BOOL(RACTuple *signals) {
      return ((UIButton *)[signals first]).highlighted;
    }]  subscribeNext:^(RACTuple *signals) {
      if ([signals.second boolValue])
      {
          [self doLogin];
      }
      else
      {
          [self error];
      }
    }];

但是这样我必须过滤按钮突出显示的状态,否则每次某些文本字段更改时subscribeNext:块都会被触发(textFieldsCombinedSignal)。

我很乐意实现这一点,而无需过滤突出显示的按钮的状态(毕竟我正在使用ReactiveCocoa来最小化状态,而且我觉得这不是我正在尝试做的事情的正确方法做)。

2 个答案:

答案 0 :(得分:1)

听起来你只想在按下按钮时对textFieldsCombinedSignal进行采样。尝试使用-sample:

RACSignal *buttonSignal = [self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside];
[[textFieldsCombinedSignal sample:buttonSignal] subscribeNext:^(RACTuple *combinedTextFields) {
    // do stuff with combinedTextFields
}];

答案 1 :(得分:1)

如果您需要一系列按钮点按,然后组合文本字段信号中的最新信息,则可以像使用-flattenMap:一样简单:

[[[self.loginButton
    rac_signalForControlEvents:UIControlEventTouchUpInside]
    flattenMap:^(id _) {
        return [textFieldsCombinedSignal take:1];
    }]
    subscribeNext:^…];

但是,根据您的描述,这似乎是RACCommand的典型案例。此代码和原始代码都允许用户双击登录按钮并触发并发登录。

在显示RACCommand之前,我会对您的代码做一些假设。仅从名称textFieldsCombinedSignal开始,它可能是一个发送字符串元组的信号,但在您的使用中,它看起来实际上是一个发送YES / NO的验证信号。我将假设后者并将其重命名为loginIsValid。我还假设-doLogin在本例中是同步的。

现在到RACCommand

self.loginButton.rac_command = [[RACCommand alloc] initWithEnabledSignal:loginIsValid signalBlock:^(id _) {
    return [RACSignal defer:^{
        [self doLogin];
        return [RACSignal empty];
    }];
}];

这将根据loginIsValid上发送的最新值启用/禁用登录按钮。启用后,点击该按钮将导致-doLogin被调用,并且该按钮将在登录过程中被禁用,从而阻止并发登录。