Metadata
- Source
- FLUID-6517
- Type
- Improvement
- Priority
- Major
- Status
- Open
- Resolution
- N/A
- Assignee
- Antranig Basman
- Reporter
- Philip Tchernavskij
- Created
2020-06-10T12:51:32.845-0400 - Updated
2021-07-27T11:55:06.618-0400 - Versions
-
- 3.0
- Fixed Versions
- N/A
- Component
-
- Data Binder
Description
In general, it should be possible for options provided at component construction to override any options in the defaults of the constructed component. However, in some cases, using (implicit) model relays in components causes construction options to be discarded in favor of default options.
In the below example, the constructed modelRelayConflictsImplicit component will end up with the model value "grade defaults value", while modelRelayConflictsExplicit will end up with the model value "construction options value":
fluid.defaults('fluid.tests.modelRelayConflicts', {
gradeNames: 'fluid.modelComponent',
model: {
value: 'grade defaults value'
}
});
var modelRelayConflictImplicit = fluid.construct('implicitParentComponent', {
type: 'fluid.tests.modelRelayConflicts',
model: {
value: '{that}.subComponent.model.value'
},
components: {
childComponent: {
type: 'fluid.modelComponent',
options: {
model: {
value: 'sub-component construction options value'
}
}
}
}
});
var modelRelayConflictsExplicit = fluid.construct('explicitParentComponent', {
type: 'fluid.tests.modelRelayConflicts',
model: {
value: 'construction options value'
},
components: {
subComponent: {
type: 'fluid.modelComponent',
options: {
model: {
value: 'sub-component construction options value'
}
}
}
},
modelRelay: {
source: '{that}.subComponent.model.value',
target: 'value',
singleTransform: {
type: 'fluid.transforms.identity'
}
}
});
Comments
-
Antranig Basman commented
2020-06-12T07:36:40.212-0400 This is a rather tough issue that I have feared for a while - the issue is that options merging occurs for each component separately, meaning that by the time the merged model specification reaches the beginning of the model transaction, it is too late to determine that one component's model is derived from material which should have higher priority than another (e.g. that it arose from a subcomponent override). In general our architecture for this is very bad and old, leading to issues like https://issues.fluidproject.org/browse/FLUID-6219 - there won't be a comprehensive solution to this until the work involving FLUID-5304. On the other hand, we have been increasingly subverting the options merging machinery and at least for problems like this one, there is a possibility we could fish the information about the model's provenance back out again using an elaborated version of the "deferringMergePolicy" that we use for most sensitive options these days as seen at https://github.com/amb26/infusion/blob/FLUID-6145/src/framework/core/js/Fluid.js#L2799 or else we could go whole hog and simply have DataBinding inspect the raw "mergeBlocks" as they sit inside the merging machinery.
You've spotted that using an explicit model relay can influence the problem - this appears to give a workaround in your case although as written this is probably indeterminate and likely just due to its disturbing the application order of the initial models. To make this reliable, you could use an annotation in your explicit model relay such as
backward: { excludeSource: "init" },
as found at https://github.com/amb26/infusion/blob/FLUID-6145/tests/framework-tests/core/js/DataBindingTests.js#L730
to prevent the model sloshing in the wrong direction, together with an appropriate comment : P