<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SAPUI5 XMLCompsite aggregation factory binding issue</title>
<script id="sap-ui-bootstrap"
src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_belize"
data-sap-ui-libs="sap.m, sap.ui.layout, sap.tnt"
data-sap-ui-resourceroots='{"BlocksIssue": "./"}'
data-sap-ui-bindingSyntax="complex"
data-sap-ui-async="true">
</script>
<script>
sap.ui.getCore().attachInit(function () {
sap.ui.require([
"sap/ui/core/mvc/XMLView"
], function (XMLView) {
XMLView.create({viewName: "BlocksIssue.App"}).then(function (oView) {
oView.placeAt("content");
});
});
});
</script>
</head>
<body class="sapUiBody" id="content"></body>
</html>
# Reproduction steps
Use segmented buttons to switch between **blue** and **red** block in object page sub section.
# Issue
Switching blocks causes an error log message:
**Cannot remove aggregated child without aggregation name.**
Basically, this error message is not breaking the application but is confusing and leads to the assumption of invalid coding.
# Cause
The error message is logged by the _\_removeChild_ method of the _ManagedObject_ implementation due to missing _sAggregationName_ argument.
This missing argument seems to be originated in the overridden *addAggregation*
method of the *ObjectPageSubSection* implementation, where *setParent* is called
without an aggregation name argument:
```
ObjectPageSubSection.prototype.addAggregation = function (sAggregationName, oObject, bSuppressInvalidate) {
...
if (this.hasProxy(sAggregationName)) {
...
if (oObject instanceof BlockBase || ...) {
// setParent called without aggregation name argument:
oObject.setParent(this);
}
return this;
}
...
};
```
sap.ui.define([
"sap/ui/core/mvc/Controller",
"BlocksIssue/BlockBlue",
"BlocksIssue/BlockRed"
], function (Controller, BlockBlue, BlockRed) {
"use strict";
return Controller.extend("BlocksIssue.App", {
onSelectionChange: function(oEvent) {
var sKey = oEvent.getSource().getSelectedKey();
var oSubSection = this.byId("subSection");
oSubSection.destroyBlocks();
var oNewBlock = sKey === "blue" ? new BlockBlue() : new BlockRed();
oSubSection.addBlock(oNewBlock);
}
});
});
<mvc:View
controllerName="BlocksIssue.App"
displayBlock="true"
xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core"
xmlns:m="sap.m"
xmlns:block="BlocksIssue"
xmlns="sap.uxap">
<m:App id="app">
<ObjectPageLayout enableLazyLoading="true">
<headerTitle>
<ObjectPageDynamicHeaderTitle>
<heading>
<m:Title text="SAPUI5 ObjectPageSubSection blocks update issue" />
</heading>
</ObjectPageDynamicHeaderTitle>
</headerTitle>
<sections>
<ObjectPageSection title="Section">
<ObjectPageSubSection id="subSection">
<actions>
<m:SegmentedButton width="10rem" selectedKey="blue" selectionChange=".onSelectionChange">
<m:items>
<m:SegmentedButtonItem text="Blue" key="blue" />
<m:SegmentedButtonItem text="Red" key="red" />
</m:items>
</m:SegmentedButton>
</actions>
<blocks>
<block:BlockBlue />
</blocks>
</ObjectPageSubSection>
</ObjectPageSection>
</sections>
</ObjectPageLayout>
</m:App>
</mvc:View>
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns:html="http://www.w3.org/1999/xhtml">
<html:div style="height:4em; background-color: #A9EAFF ;" />
</mvc:View>
sap.ui.define(['sap/uxap/BlockBase'],
function (BlockBase) {
"use strict";
var BlockBlue = BlockBase.extend("BlocksIssue.BlockBlue", {
metadata: {
views: {
Collapsed: {
viewName: "BlocksIssue.BlockBlue",
type: "XML"
},
Expanded: {
viewName: "BlocksIssue.BlockBlue",
type: "XML"
}
}
},
renderer: {}
});
return BlockBlue;
});
<mvc:View
xmlns:mvc="sap.ui.core.mvc"
xmlns:html="http://www.w3.org/1999/xhtml">
<html:div style="height:4em; background-color: #EC7063 ;"/>
</mvc:View>
sap.ui.define(['sap/uxap/BlockBase'],
function (BlockBase) {
"use strict";
var BlockRed = BlockBase.extend("BlocksIssue.BlockRed", {
metadata: {
views: {
Collapsed: {
viewName: "BlocksIssue.BlockRed",
type: "XML"
},
Expanded: {
viewName: "BlocksIssue.BlockRed",
type: "XML"
}
}
},
renderer: {}
});
return BlockRed;
});