如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?

Posted

技术标签:

【中文标题】如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?【英文标题】:How to display bound NSManagedObject's property based on complex user's choice? 【发布时间】:2015-03-20 14:46:41 【问题描述】:

在我使用Core Data 的项目中,我大量使用NArrayController 和绑定,它运行良好。有时我需要根据用户选择来转换 NSManagedObject's 属性表示(它是 UI 中的表示)。

例如,我有一个实体“事件”,它有一个属性“距离”。用户可以选择如何显示它:米、公里、英里。对于这样简单的任务,我使用NSValueTransform

但是如何管理更复杂的场景呢?例如,我有一个实体 'Fault',它有一个属性 'errorValue'。用户在 UI 中输入一个修正值,我们将其命名为“faultCorrection”。之后,我需要在任何地方将“Fault.errorValue”显示为“fault.errorValue - faultCorrection”。

目前,为此我有一些基于NSValueTransform 的丑陋解决方案,具有静态属性。此类任务有什么好的解决方案吗?

【问题讨论】:

【参考方案1】:

我对这个主题做了一些额外的研究,似乎这个问题没有完美的解决方案,你要么需要打破 MVC 模式,要么使用静态变量或使用 userDefaults(正如 stevesliva 所指出的那样)。我找到了另一种解决方案。如果在代码中完成绑定,则可能会使用 nsvaluetransform 后代的特定实例。

变形金刚声明:

@interface FaultCorrection : NSValueTransformer

-(void)setCorrection:(NSInteger)value;

@end

绑定,在代码中使用了以下变量:

self.tableView - NSTableView self.ctrl - NSArrayController self.transformer - FaultCorrection

-(void)bindIt 
   NSDictionary * opt = nil;

if ( self.transformer ) opt = [ NSDictionary dictionaryWithObject:self.transformer forKey:NSValueTransformerBindingOption ];

[ self.tableView bind:NSContentBinding toObject:self.ctrl withKeyPath:@"arrangedObjects" options:nil ]; [ self.tableView.tableColumns[0] bind:NSValueBinding toObject:self.ctrl withKeyPath:@"arrangedObjects" options:opt ];

当用户更改faultCorrection时调用该方法:

-(void)update 
  [ self.transformer setCorrection: [self.fieldCorrection intValue]];
  [ self.tableView reloadData ];

【讨论】:

【参考方案2】:

在将视图绑定到实体属性的位置进行值转换实际上可能是最 MVC 分离事物的方式。事实上,这可能是最好的方法,因为如果您可以实现反向转换,您将获得双向绑定。所以,简而言之,没有更好的解决方案。只是不同而已。

但在您的情况下,我可能会在实体的支持类上实现另一个符合 KVC 的属性。 displayValue 之类的东西,并绑定到它。如果我在 IB 中查找绑定,我发现代码更容易理解,看到它是“displayValue”,然后找到适当的方法。

但问题在于,听起来faultCorrection 是应用程序或视图状态的一部分,而不是实例/实体状态,因此任何displayValue 方法仍然需要在某处查询单例。您说目前这些是静态属性。最好使用符合绑定的[NSUserDefaultsController sharedUserDefaultsController]

所以,说了这么多,要绑定到的实体类上是这样的:

- (NSString*) displayValue

    NSUserDefaultsController* defaults = NSUserDefaultsController.sharedUserDefaultsController;
    NSNumber* faultCorrection = [defaults valueForKeyPath:@"faultCorrection"];
    return [NSString stringWithFormat:@"%d",self.errorValue.floatValue - faultCorrection.floatValue];

+ (NSSet*) keyPathsForValuesAffectingDisplayValue 

    return [NSSet setWithObject:@"errorValue"];

但是,如果用户更改 sharedUserDefaults 中的 faultCorrection 值,您必须弄清楚如何重新触发 displayValue 绑定 KVO。你如何做到这一点取决于用户设置它的位置。您的 valueTransformers 当前使用的任何静态值都存在同样的问题——没有实例 keyPathForValuesAffecting... 可用于将静态值注册为相关键路径的方法。让每个实体实例 KVO 观察 sharedUserDefaults 可能是矫枉过正,如果您可以将 ViewController 吹走并重新初始化它。

另外,顺便说一句,这与this recent question所涵盖的主题非常相似

【讨论】:

感谢您的回答,看来这个任务没有完美的解决方案,我找到了另一个解决方案,并将其作为附加答案发布,也许对 smb 有帮助。

以上是关于如何根据复杂用户的选择显示绑定的 NSManagedObject 的属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据布尔值 (SwiftUI) 更改对象的绑定源?

Repeater中 DropDownList如何绑定数据

根据用户选择顺序保存多个选择的ngModel绑定值

C#中 combox控件已绑定数据, 如何根据一个string类型字段 设置combox的选择项

如何根据 Shiny R 中的用户选择在 MainPanel 中显示数据?

如何根据用户选择在 CollectionView 标题下方显示不同的单元格?