Binding 为什么没有调用我的被动Cocoa来检查textfield的更改?

Binding 为什么没有调用我的被动Cocoa来检查textfield的更改?,binding,reactive-cocoa,Binding,Reactive Cocoa,我是RCA的新手。我在网上找到这个图坦卡蒙 这很简单…在原始项目中,它们将模型与视图控制器分开,这是它们应该的:)但是当我尝试这样做时,我无法将视图控制器属性绑定(或连接)到模型属性 所有的设置都是正确的,因为如果我把所有的代码都放在视图控制器类中,它就会工作! 它工作的原因是,我不需要视图控制器中将模型绑定到视图控制器属性的代码行 但是,当我试图按照教程中的方法将其拆分时,我在那一行得到了一个错误 当在视图控制器中: [[self.usernameField.rac_textSignal di

我是RCA的新手。我在网上找到这个图坦卡蒙

这很简单…在原始项目中,它们将模型与视图控制器分开,这是它们应该的:)但是当我尝试这样做时,我无法将视图控制器属性绑定(或连接)到模型属性

所有的设置都是正确的,因为如果我把所有的代码都放在视图控制器类中,它就会工作! 它工作的原因是,我不需要视图控制器中将模型绑定到视图控制器属性的代码行

但是,当我试图按照教程中的方法将其拆分时,我在那一行得到了一个错误

当在视图控制器中:

[[self.usernameField.rac_textSignal distinctUntilChanged] subscribeNext:^(NSString *x) {self.username = x;}];

 [self.mymodel.forbiddenNameSignal subscribeNext:^(NSString *name) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Forbidden Name!"
                                                            message:[NSString stringWithFormat:@"The name %@ has been forbidden!",name]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
            [alert show];
            self.mymodel.username = @"";
 }];
信号法

-(RACSignal *)forbiddenNameSignal {
    return [RACObserve(self, username) filter:^BOOL(NSString *newName) {
        return [self.forbiddenNames containsObject:newName]; //This yields a YES BOOLEAN?
    }];
}
这将进入viewController的viewDidLoad中:

[[self.usernameField.rac_textSignal distinctUntilChanged] subscribeNext:^(NSString *x) {self.username = x;}];

 [self.mymodel.forbiddenNameSignal subscribeNext:^(NSString *name) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Forbidden Name!"
                                                            message:[NSString stringWithFormat:@"The name %@ has been forbidden!",name]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
            [alert show];
            self.mymodel.username = @"";
 }];
当然,UITextField位于故事板中并已连接,禁止数组也在viewDidLoad中定义

这不起作用:

LoginModel.m

-(id)init {
    self = [super init];
    if(!self) return nil;
    //forbidden names array
    self.forbiddenNames = @[ @"Peter",@"Piper",@"Picker"];
    return self;
}


-(RACSignal *)forbiddenNameSignal {
    return [RACObserve(self, username) filter:^BOOL(NSString *newName) {
        return [self.forbiddenNames containsObject:newName]; //This yields a YES BOOLEAN?
    }];
}
ViewController.m viewDidLoad:

self.mymodel = [LoginModel new];
RAC(self.usernameField.text) = [RACAbleWithStart(self.mymodel.username) distinctUntilChanged];
[[self.usernameField.rac_textSignal distinctUntilChanged] subscribeNext:^(NSString *x) {
            self.username = x;
        }];
[self.mymodel.forbiddenNameSignal subscribeNext:^(NSString *name) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Forbidden Name!"
                                                            message:[NSString stringWithFormat:@"The name %@ has been forbidden!",name]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
            [alert show];
            self.mymodel.username = @"";
        }];
我在RAC行中得到一个错误,表示“valuesForKeyPath”不推荐使用“signalWithStarting…”的预期标识符和警告

我所尝试的:

RAC(self, usernameField) = [RACObserve(self, mymodel.username) distinctUntilChanged];
而且

RAC(self, usernameField) = RAC(self, mymodel.username);
有没有办法解决这个问题


或者关于缩进代码不起作用的原因:(

我不确定我是否完全理解您的问题,但您的代码中有一些不正确的地方

首先,请谨慎对待web上有关ReactiveCocoa的教程!几个月前ReactiveCocoa 2.0发布时,API发生了许多重大变化。您一直在尝试使用的RACAbleWithStart宏

此外,在我看来,此代码是错误的:

[[self.usernameField.rac_textSignal distinctUntilChanged]
    subscribeNext:^(NSString *x) {self.username = x;}];
这是采用
rac_textSignal
并将下一个事件值分配给
username
属性。首先,我非常确定这里不需要
distinctunitrichanged
,信号只会在文本字段更改时发出事件。其次,要将a信号分配给属性,只需使用rac宏即可:

RAC(self, username) = self.usernameField.rac_textSignal;
我发现问题的根源在于您试图将
LoginModel
上的属性绑定到视图控制器中的属性。ReactiveCocoa有专门用于此目的的
RACChannelTo
宏,但我从未使用过它,而且我有一个想法可以绕过它

在我看来,您的LoginModel应该成为一个视图模型,它应该公开一个
用户名
,以便为视图建模(因为视图模型就是这样做的!)。然后,您可以在视图控制器中这样绑定它:

RAC(self.loginViewModel, username) = self.usernameField.rac_textSignal;
然后,您必须将
用户名
属性更改转换为视图模型中的信号,以便您可以使用过滤器…因此在LoginViewModel初始化代码中

[[RACObserve(self, username)
  filter:^BOOL(NSString *username) {
    return [self.forbiddenNames containsObject:username]; 
  }
  subscribeNext:^BOOL(NSString *forbiddenName) {
    // do your thang!
  }];

我希望这会有所帮助!

我不确定我是否完全理解您的问题,但您的代码中有一些地方看起来不正确

首先,请谨慎对待web上有关ReactiveCocoa的教程!几个月前ReactiveCocoa 2.0发布时,API发生了许多重大变化。您一直在尝试使用的RACAbleWithStart宏

此外,在我看来,此代码是错误的:

[[self.usernameField.rac_textSignal distinctUntilChanged]
    subscribeNext:^(NSString *x) {self.username = x;}];
这是采用
rac_textSignal
并将下一个事件值分配给
username
属性。首先,我非常确定这里不需要
distinctunitrichanged
,信号只会在文本字段更改时发出事件。其次,要将a信号分配给属性,只需使用rac宏即可:

RAC(self, username) = self.usernameField.rac_textSignal;
我发现问题的根源在于您试图将
LoginModel
上的属性绑定到视图控制器中的属性。ReactiveCocoa有专门用于此目的的
RACChannelTo
宏,但我从未使用过它,而且我有一个想法可以绕过它

在我看来,您的LoginModel应该成为一个视图模型,它应该公开一个
用户名
,以便为视图建模(因为视图模型就是这样做的!)。然后,您可以在视图控制器中这样绑定它:

RAC(self.loginViewModel, username) = self.usernameField.rac_textSignal;
然后,您必须将
用户名
属性更改转换为视图模型中的信号,以便您可以使用过滤器…因此在LoginViewModel初始化代码中

[[RACObserve(self, username)
  filter:^BOOL(NSString *username) {
    return [self.forbiddenNames containsObject:username]; 
  }
  subscribeNext:^BOOL(NSString *forbiddenName) {
    // do your thang!
  }];

我希望这会有帮助!

Thx!我得到了与RAC宏一起工作的绑定。我还消除了distinctunitrichanged,所以现在自然的问题是,distinctunitrichanged与subscribeNext有什么不同?最后,您的RACObserve过滤器:subscribeNext:一次性完成了我的代码拆分(在模型中筛选并在vc中订阅文本…对此有何想法?@marciokoko DistinctUntil更改的“筛选”值不等于上一个值。
self.viewModel.name=@“foo”;self.viewModel.name=@“foo”;
仅触发第一个调用。我想在“订阅文本”中显示警报)。那么,如何从视图模型在视图中显示警报?Thx!我获得了使用RAC宏的绑定。我还消除了distinctUntilChanged,因此现在的自然问题是,distinctUntilChanged与SubscribeText有什么不同?最后,您的RACObserve筛选器:SubscribeText:一次性完成了我的代码拆分(在模型中筛选并在vc中订阅文本…对此有何想法?@marciokoko DistinctUntil更改的“筛选”值不等于上一个值。
self.viewModel.name=@“foo”;self.viewModel.name=@“foo”;
仅触发第一个调用。我想在“订阅文本”中显示警报)。那么如何从视图模型在视图中显示警报?