【问题标题】:How to connect Model through Controller to View using bindings?如何使用绑定通过控制器将模型连接到视图?
【发布时间】:2010-03-17 13:17:28
【问题描述】:

我认为我有一个NSTextField。它的值绑定到我的控制器中的NSNumber *number。控制器只需调用模型 (value) 即可获取适当的值。

// In the controller
- (NSNumber *)number {
    return [NSNumber numberWithFloat:[model value]];
}
- (void)setNumber:(NSNumber *)aNumber {
    [model setValue:[aNumber floatValue]];
}

这很好,只有控制器不会收到模型更改通知,因此,更改模型中的值不会更新 NSTextField

我能想到的唯一其他选择是让模型通知控制器,控制器通过 Outlet 手动更新视图。但这绕过了绑定。

// In the model, after value change
[[NSNotificationCenter defaultCenter] postNotificationName:@"ValueChanged" object:self];

// In the controller, after being notified
- (void)updateView:(NSNotification *)aNotification {
    [myTextField setFloatValue:[model value]];
}

有没有更好的绑定感知方式来实现这种通信?

【问题讨论】:

    标签: objective-c cocoa model-view-controller binding


    【解决方案1】:

    我的视图中有一个 NSTextField。它的值绑定到我的控制器中的 NSNumber *number。控制器只需调用模型(值)即可获得适当的值。

    为什么这个属性将值包装在一个 NSNumber 中? KVC 将为您在对象之间转换原始值,例如 floats。

    这很好,只有控制器不会收到模型更改的通知,因此,更改模型中的值不会更新 NSTextField。

    模型更改在这里无关紧要,控制器不需要知道模型属性更改的值,除非控制器正在观察该属性 - 在这种情况下,控制器 em> 收到有关这些更改的通知,因为您正在使用模型的属性访问器。

    问题在于您没有通过模型绑定文本字段——而是将其绑定到控制器上的假属性。

    因此,假设控制器已经公开了模型对象的属性,只需将文本字段绑定到具有键路径 model.value 的控制器。

    【讨论】:

      【解决方案2】:

      在您的控制器中,覆盖 keyPathsForValuesAffectingValueForKey: 类方法。类似的东西:

      +(NSSet*) keyPathsForValuesAffectingValueForKey:(NSString*)key
      {
         if([key isEqual:@"number"])
            return [NSSet setWithObject:@"model.value"];
         return [NSSet set];
      }
      

      (我不在我的 Mac 上,所以这是未经测试的;但总体思路应该是合理的)

      【讨论】:

        【解决方案3】:

        另一种选择(以及我通常自己做的,纯粹出于个人喜好)类似于(在控制器中):

        -(void)setModel:(id)m
        {
           [model removeObserver:self forKeyPath:@"value"];
        
           [m retain];
           [model release];
           model = m;
        
           [model addObserver:(self) forKeyPath:@"value" options:NSKeyValueObservingOptionNew context:NULL];
        }
        
        -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
        {
           if([keyPath isEqual:@"value"])
           {
              [self willChangeValueForKey:@"number"];
              [self didChangeValueForKey:@"number"];
           }  
        }
        

        同样,此代码未经测试,但总体思路应该可行。

        【讨论】:

        • 绑定到模型中是个好主意吗?我对此有一种奇怪的不好的感觉,我无法解释。
        • 嗯,这不是绑定。是KVO。绑定建立在 KVO 之上,但 KVO 是独立的。而且我不知道这是个好主意还是坏主意。 KVO 只是一个工具。我喜欢让我的控制器观察我的视图,因为它对我的耦合度较低。模型甚至不必知道控制器的存在。我确信存在其他观点。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-09
        • 2022-10-14
        • 2015-10-07
        相关资源
        最近更新 更多