【问题标题】:bind:toObject:withKeyPath:options: is one-way binding?bind:toObject:withKeyPath:options: 是单向绑定吗?
【发布时间】:2013-02-08 14:59:53
【问题描述】:

我有两个窗口:窗口 A 从 NIB 加载;窗口 B 是通过编程方式创建的。

两个窗口都有一个 NStextView:窗口 A 中 textview 的 attributesString 绑定到 使用 IB 的模型的属性 text;而窗口 B 中 textview 的 attributesString 使用 -[NSObject bind:toObject:withKeyPath:options:] 方法绑定到模型的 text 属性。

[textview bind:@"attributedString"
      toObject:obj
   withKeyPath:@"text"
       options:nil];

奇怪的是:Window B 中的 textview 确实绑定到了obj.text,但是 textview 中的更改从未更新为obj.text。但是,如果我对 Window A 的 textview 进行了更改,则 obj.text 和 Window B 中的 textview 也会相应地更新。

所以我在想,-[NSObject bind:toObject:withKeyPath:options:] 方法仅适用于单向绑定。我在 Cocoa 文档中找不到明确的解释。有没有人有这个问题的经验?如何在代码中实现双向绑定?

【问题讨论】:

    标签: cocoa binding cocoa-bindings nstextview


    【解决方案1】:

    Cocoa 绑定本质上是双向的,但某些行为(如文本字段的持续/实时更新)需要设置特定选项。在 IB 中,您需要确保选中“持续更新值”复选框。要以编程方式获得等效行为,您需要在绑定上指定 options。这可能看起来像这样:

    [textview bind: NSAttributedStringBinding 
          toObject: obj 
       withKeyPath: @"text" 
           options: (@{ 
                     NSContinuouslyUpdatesValueBindingOption : @YES })];
    

    值得一提的是,在以编程方式设置绑定时,值得检查 IB 中的等效绑定并确保将所有相同的设置传递给编程绑定。例如,我在 IB 中看到“允许编辑多个值选择”、“有条件地设置可编辑”和“为不适用的键引发”选项默认情况下都会检查 NSTextView 的属性字符串绑定。这意味着我们的编程绑定应该真的看起来像:

    [textview bind: NSAttributedStringBinding 
          toObject: obj 
       withKeyPath: @"text" 
           options: (@{ 
                     NSContinuouslyUpdatesValueBindingOption : @YES,
                     NSAllowsEditingMultipleValuesSelectionBindingOption : @YES,
                     NSConditionallySetsEditableBindingOption : @YES,
                     NSRaisesForNotApplicableKeysBindingOption : @YES })];
    

    【讨论】:

    • 这仍然不适合我。我在这里找到了答案(就我而言) --> stackoverflow.com/questions/1169097/…
    • 我不确定上述链接问题的相关性。这里提到的绑定是在两个 NSControl 对象之间——不需要自定义绑定实现。
    • 固有的双向是什么意思?我在两个对象之间有一个只能单向工作的绑定。这是 IB 的特例吗?
    • @JulianF.Weinert 我的意思是,如果您将控件绑定到模型对象(在常见情况下通过 Controller),则该字段将从该模型对象填充其值(即读取),然后用户在控件中所做的任何更改都将被推回模型对象(即写入)。就是这样。
    • 你知道这个功能在哪一层吗?我想应该是NSControl,对吧?对于 vanilla NSObject 子类,它只能单向工作
    【解决方案2】:

    是的,bind: toObject: withKeyPath: options: 是一种方式,没有任何选项可以影响这一点。这与您在 .nib 文件中进行绑定不同。像往常一样,Apple 忘记在其文档中提及如此简单的事情。这里最简单的解决方案是在创建正向绑定的同时创建反向绑定。 当您分配值时,这不会死循环您的代码。 这是用户默认值的示例:

    // two way binding of MyObject.myValue to user defaults
    [NSUserDefaultsController.sharedUserDefaultsController.values bind: @"myValueInDefaults"
                                                              toObject: myObject
                                                           withKeyPath: @"myValue"
                                                               options: @{@"NSContinuouslyUpdatesValue":@YES}];
    
    [myObject bind: @"myValue"
          toObject: NSUserDefaultsController.sharedUserDefaultsController
       withKeyPath: @"values.myValueInDefaults"
           options: @{@"NSContinuouslyUpdatesValue":@YES}];
    

    【讨论】:

    • 是否需要使用两个 NSValueTransformer,如果我需要将一个值转换为另一个值,反之亦然,对于键 NSValueTransformerBindingOption,或者一个就足够了?
    • 由于这些绑定没有相互连接,我认为您需要两个 NSValueTransformer,每个绑定一个。但我没有使用过 NSValueTransformerBindingOption 也无法确定。
    • 我明白了,例如从度数到弧度,反之亦然,我认为需要其中两个,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 1970-01-01
    • 2013-02-06
    • 2013-06-28
    • 2012-02-11
    • 1970-01-01
    • 2016-07-06
    相关资源
    最近更新 更多