以父/子关系将数据从工作表传递到 insertNewObject

发布于 2024-12-28 14:19:15 字数 2165 浏览 1 评论 0原文

我在作为父/子关系中的子实体的实体中 insertNewObject 时遇到问题。它是一个具有本地 SQLite 基础的 CoreData 应用程序。主窗口上有 2 个实体和 2 个 TableView。使用 contentSet,子表将仅显示与所选父级相关的数据。

向子级添加数据是通过显示一张包含来自第三个实体的项目表的工作表来完成的。用户必须从此表中进行选择,然后单击“添加”。关闭工作表时,主窗口上的子表应使用新行进行更新。问题:什么也没有出现。

使用第三方应用程序检查数据库内容,我看到新数据在那里,但它没有出现在表视图上,因为没有存储与父级关系的信息,所以它不知道它是哪个父级相关。

我的代码缺少有关此的信息,但我只是不知道应该如何对其进行编程。换句话说:在关闭工作表上,确定选择了哪个父级,并在子级中插入新数据时指定此关系信息。我将不胜感激任何帮助。

这是我的代码:

  // there are 3 entities: Collectors (parent), CollectedItems (child) and Items.

  // we call the sheet presenting the Items list to pick from
  - (IBAction)showAddItemDialog:(id)sender {
    [NSApp beginSheet:addItemDialog
modalForWindow:window
modalDelegate:self
    didEndSelector:@selector(didEndAddItemSheet:returnCode:contextInfo:)
    contextInfo:nil];
  }

  // we dismiss the sheet by clicking on Cancel or Add
  - (IBAction)dismissAddItemDialog:(id)sender {
[NSApp endSheet:addItemDialog returnCode:([sender tag])];
    [addItemDialog orderOut:sender];
  }

  // depending on clicked button, do nothing or pass selected data
  - (void)didEndAddItemSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo (void *)contextInfo {
    if (returnCode == 0) {
    // do nothing, this is the effect of clicking on Cancel
    }
    if (returnCode == 1) {
    NSString *theName = [[[itemsPickerController selectedObjects] valueForKey:@"itemName"] objectAtIndex:0];
    // above, we get the value from the itemName attribute sleected in the Items list
    NSLog (@"%@", theName);
    // the variable is displayed in the console, so it was correctly selected
    [self addNewItemWithName:theName];
    }
  }

  // we use the passed data to create new object (row) in the CollectedItems entity
  - (id)addNewItemWithName:(NSString *)theName {
    NSEntityDescription *newContent = [NSEntityDescription insertNewObjectForEntityForName:@"CollectedItems" inManagedObjectContext:[self managedObjectContext]];
    [newContent setValue:theName forKey:@"collectedItemName"];
    // above, we insert a new row in CollectedItems, assigning the value theName to the attribute collectedItemName
    return nil;
  }

I have a problem to insertNewObject in an entity being the child in a parent/child relationship. It's a CoreData app with a local SQLite base. There are 2 entities presented with 2 TableViews on the main window. Using contentSet, the table for the child will only show data relating to the selected parent.

Adding data to the child is done by showing a sheet with a table of items coming from a 3rd entity. User must pick from this table then click Add. On dismissing the sheet, the child table on main window should be updated with a new row. Problem: nothing appears.

Checking the database content with a third-party app, I see that the new data is there but it doesn't appear on the table view because no info on the relationship with parent was stored, so it doesn't know to which parent it relates.

My code is missing info about this but I just don't see how I should program this. In other words: on dismissing sheet, identify which parent is selected and specify this relationship info when inserting the new data in the child. I would appreciate any help.

Here is my code:

  // there are 3 entities: Collectors (parent), CollectedItems (child) and Items.

  // we call the sheet presenting the Items list to pick from
  - (IBAction)showAddItemDialog:(id)sender {
    [NSApp beginSheet:addItemDialog
modalForWindow:window
modalDelegate:self
    didEndSelector:@selector(didEndAddItemSheet:returnCode:contextInfo:)
    contextInfo:nil];
  }

  // we dismiss the sheet by clicking on Cancel or Add
  - (IBAction)dismissAddItemDialog:(id)sender {
[NSApp endSheet:addItemDialog returnCode:([sender tag])];
    [addItemDialog orderOut:sender];
  }

  // depending on clicked button, do nothing or pass selected data
  - (void)didEndAddItemSheet:(NSWindow *)sheet returnCode:(int)returnCode contextInfo (void *)contextInfo {
    if (returnCode == 0) {
    // do nothing, this is the effect of clicking on Cancel
    }
    if (returnCode == 1) {
    NSString *theName = [[[itemsPickerController selectedObjects] valueForKey:@"itemName"] objectAtIndex:0];
    // above, we get the value from the itemName attribute sleected in the Items list
    NSLog (@"%@", theName);
    // the variable is displayed in the console, so it was correctly selected
    [self addNewItemWithName:theName];
    }
  }

  // we use the passed data to create new object (row) in the CollectedItems entity
  - (id)addNewItemWithName:(NSString *)theName {
    NSEntityDescription *newContent = [NSEntityDescription insertNewObjectForEntityForName:@"CollectedItems" inManagedObjectContext:[self managedObjectContext]];
    [newContent setValue:theName forKey:@"collectedItemName"];
    // above, we insert a new row in CollectedItems, assigning the value theName to the attribute collectedItemName
    return nil;
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如梦亦如幻 2025-01-04 14:19:15

您需要添加您创建的 CollectedItems 对象与其父 Collectors 对象之间的关系。 Collectors 将有一个核心数据实用方法(如果您已生成核心数据管理对象类)。它将被称为类似 addCollectedItemsObject 的名称。

重新加载 tableViews 然后应该使用正确的数据进行更新 - 因为它现在知道关系。

更好的是使用 NSFetchedResultsController 来控制表中的数据,以便当您更新数据模型时,表将自动反映更改。

You need to add the relationship between your CollectedItems object you created and its parent the Collectors object. Collectors will have a core data utility method on it (if you have generated the core data managed object classes). It will be called something like addCollectedItemsObject.

Reloading the tableViews should then update with the correct data - as it now knows the relationship.

Even better would be to use NSFetchedResultsController to control the data in your tables so that when you update your data model, the tables will automatically reflect the changes.

戴着白色围巾的女孩 2025-01-04 14:19:15

为了记录,对于那些可能有帮助的人,这里是最终的工作代码:

确保在(核心数据管理对象类)的相应收集器类文件中生成该方法。

// header file
@class Collecteditems;
@interface Collectors : NSManagedObject { }
@property (nonatomic, retain) NSSet* content;
@end
@interface Collectors (CoreDataGeneratedAccessors)
- (void)addContentObject:(Collecteditems *)value;
@end

// implementation file
#import "Collectors.h"
#import "Collecteditems.h"
@implementation Collectors 
@dynamic content;
- (void)addContentObject:(Collecteditems *)value {
NSSet *s = [NSSet setWithObject:value];
[self willChangeValueForKey:@"collecteditems" withSetMutation:NSKeyValueUnionSetMutation usingObjects:s];
[[self primitiveValueForKey:@"collecteditems"] addObject:value];
[self didChangeValueForKey:@"collecteditems" withSetMutation:NSKeyValueMinusSetMutation usingObjects:s];
}

然后在 NSArrayController 上添加 addObject 方法来控制收集的项目表(请参阅原始帖子中的 id 以供参考)。

- (id)addNewItemWithName:(NSString *)theName {
    NSEntityDescription *newContent = [NSEntityDescription insertNewObjectForEntityForName:@"CollectedItems" inManagedObjectContext:[self managedObjectContext]];
    [newContent setValue:theName forKey:@"collectedItemName"];
    [collectedItemsController addObject:newContent]; // line added
    return nil;
  }

And for the record, for those it might help, here is the final working code:

Ensuring the method was generated in the corresponding Collectors class file for (core data managed object classes).

// header file
@class Collecteditems;
@interface Collectors : NSManagedObject { }
@property (nonatomic, retain) NSSet* content;
@end
@interface Collectors (CoreDataGeneratedAccessors)
- (void)addContentObject:(Collecteditems *)value;
@end

// implementation file
#import "Collectors.h"
#import "Collecteditems.h"
@implementation Collectors 
@dynamic content;
- (void)addContentObject:(Collecteditems *)value {
NSSet *s = [NSSet setWithObject:value];
[self willChangeValueForKey:@"collecteditems" withSetMutation:NSKeyValueUnionSetMutation usingObjects:s];
[[self primitiveValueForKey:@"collecteditems"] addObject:value];
[self didChangeValueForKey:@"collecteditems" withSetMutation:NSKeyValueMinusSetMutation usingObjects:s];
}

Then adding the addObject method on the NSArrayController controlling the collected items table (see id in original post for reference).

- (id)addNewItemWithName:(NSString *)theName {
    NSEntityDescription *newContent = [NSEntityDescription insertNewObjectForEntityForName:@"CollectedItems" inManagedObjectContext:[self managedObjectContext]];
    [newContent setValue:theName forKey:@"collectedItemName"];
    [collectedItemsController addObject:newContent]; // line added
    return nil;
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文