2014-05-23 10 views
1

我正在用QuickDialog和Reactive Cocoa構建一個相當長的窗體,我希望能夠編寫一個工廠方法來設置我的QElements形成。構建一個工廠方法來創建QuickDialog Entry元素綁定到RAC查看模型

這是我現在如何做的例子。

self.root = [[QRootElement alloc] init]; 
self.root.title = self.title; 
self.root.grouped = YES; 

self.basic = [[QSection alloc] init]; 
self.basic.title = @"Basic Information"; 
[self.root addSection:self.basic]; 

QEntryElement *address = [[QEntryElement alloc] init]; 
address.title = @"Address"; 
RAC(address, textValue) = [RACObserve(self, viewModel.address) distinctUntilChanged]; 
RAC(self, viewModel.address) = [RACObserve(address, textValue) distinctUntilChanged]; 
[self.basic addElement:address]; 

QEntryElement *city = [[QEntryElement alloc] init]; 
city.title = @"City"; 
RAC(city, textValue) = [RACObserve(self, viewModel.city) distinctUntilChanged]; 
RAC(self, viewModel.city) = [RACObserve(city, textValue) distinctUntilChanged]; 
[self.basic addElement:city]; 

QEntryElement *state = [[QEntryElement alloc] init]; 
state.title = @"State"; 
RAC(state, textValue) = [RACObserve(self, viewModel.state) distinctUntilChanged]; 
RAC(self, viewModel.state) = [RACObserve(state, textValue) distinctUntilChanged]; 
[self.basic addElement:state]; 

QEntryElement *postal = [[QEntryElement alloc] init]; 
postal.title = @"Zip"; 
RAC(postal, textValue) = [RACObserve(self, viewModel.postalCode) distinctUntilChanged]; 
RAC(self, viewModel.postalCode) = [RACObserve(postal, textValue) distinctUntilChanged]; 
[self.basic addElement:postal]; 

QEntryElement *phone = [[QEntryElement alloc] init]; 
phone.title = @"Phone"; 
RAC(phone, textValue) = [RACObserve(self, viewModel.phoneNumber) distinctUntilChanged]; 
RAC(self, viewModel.phoneNumber) = [RACObserve(phone, textValue) distinctUntilChanged]; 
[self.basic addElement:phone]; 

我希望能夠調用的方法等:

-(QEntryElement *)racEntryElementWithTitle:(NSString *)title andModel(ViewModel *)model andProperty:(NSString*)property; 

是否有某種方式來做到這一點?

回答

1

一般來說,如果你想要雙向數據綁定,你應該使用RACChannel,所以你不必明確使用-distinctUntilChanged來防止雙向數據綁定無限循環。要使用KVO執行此操作,您需要創建兩個RACChannel(每個KVO屬性一個),並將一個頻道的followingTerminal分配給另一個的followingTerminal屬性。這通常是由RACChannelTo()宏爲您完成的,但是如果您想以NSStrings的形式動態提供密鑰路徑,則不能使用該宏;你需要深入探索並直接使用RACKVOChannel類:

(此代碼是未經測試)。

- (QEntryElement *)entryElementWithTitle:(NSString *)title boundWithModel(ViewModel *)model atKeyPath:(NSString*)keyPath 
{ 
    QEntryElement *ee = [[QEntryElement alloc] init]; 
    ee.title = title; 
    RACChannel *modelChannel = [[RACKVOChannel alloc] initWithTarget:model keyPath:keyPath nilValue:@""]; 
    RACChannelTo(ee, textValue, @"") = modelChannel.followingTerminal; 
    return ee; 
} 


// later... 

self.root = [[QRootElement alloc] init]; 
self.root.title = self.title; 
self.root.grouped = YES; 

self.basic = [[QSection alloc] init]; 
self.basic.title = @"Basic Information"; 
[self.root addSection:self.basic]; 

[self.basic addElement:[self entryElementWithTitle:@"Address" boundWithModel:self.viewModel atKeyPath:@"address"]; 
[self.basic addElement:[self entryElementWithTitle:@"City" boundWithModel:self.viewModel atKeyPath:@"city"]; 
[self.basic addElement:[self entryElementWithTitle:@"State" boundWithModel:self.viewModel atKeyPath:@"state"]; 
[self.basic addElement:[self entryElementWithTitle:@"Zip"  boundWithModel:self.viewModel atKeyPath:@"postalCode"]; 
[self.basic addElement:[self entryElementWithTitle:@"Phone" boundWithModel:self.viewModel atKeyPath:@"phoneNumber"]; 
+0

感謝埃裏克!這非常有幫助! –

0

你毫無疑問面臨的問題是那些宏。一種方法是運行預處理器來查看宏的輸出結果。

富勒例如,該行:

RAC(postal, textValue) = [RACObserve(self, viewModel.postalCode) distinctUntilChanged]; 

擴展爲以下幾點:

[[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:(postal) nilValue:(((void *)0))][@(((void)(__objc_no && ((void) postal. textValue, __objc_no)), "textValue"))] = [[(id)(self) rac_valuesForKeyPath:@(((void)(__objc_no && ((void)self.viewModel.postalCode, __objc_no)), "viewModel.postalCode")) observer:self] distinctUntilChanged]; 

這應該允許您進行參數您所需要的零件。