Sorry for necrobumping if this is an old thread. I've just had this problem, and found the (probably correct) solution.
The GridFieldDetailForm (the object that handles sub-object creations in a GridField) can have a set of fields explicitly specified during construction of the actual GridField, which occurs in the parent object's getCMSFields function.
This means you can inject a set of fields at this point, each of which is aware of the parent ID of the object this new entity is being assigned to.
In the below example, I've chosen to simply use a dummy ProductModel, passed it the ID of the parent Product, and extracted its getCMSFields. Within the ProductModel::getCMSFields function, I can now use conditional logic based on the parentID.
class Product extends Page {
public function getCMSFields() {
$fields = parent::getCMSFields();
// Models
$modelsConfig = GridFieldConfig_RecordEditor::create();
if($this->exists()) {
// Ensure that fields are generated with knowledge of the parent
$editComponent = $modelsConfig->getComponentByType('GridFieldDetailForm');
$model = new ProductModel();
$model->ProductID = $this->ID;
$editComponent->setFields($model->getCMSFields());
}
$modelsField = new GridField('Models', 'Product Models', $this->Models(), $modelsConfig);
$fields->addFieldToTab('Root.Models', $modelsField);
return $fields;
}
}
class ProductModel extends DataObject {
public function getCMSFields() {
// ... in this code $this->Product() gives me the parent product, even if ProductModel hasn't been written to the database yet
}
}
The downside of this approach, however, is that in ProductModel::getCMSFields, even if you are editing an existing record, $this->ID will be empty (since it uses the dummy object for creating the field list).