Using and Nesting Components

You can use a ComponentContainer to wrap a UIComponent and reuse it anywhere within the SAPUI5 control tree. You can use reuse components to nest components in other components.

Component Containers

To render UI components, you must wrap them in a ComponentContainer. You cannot use the placeAt method to place UI components directly in a page. A component container carries specific settings and also contains the lifecycle methods of a regular control, such as the onBeforeRendering and onAfterRendering methods. The lifecycle methods of the ComponentContainer are forwarded to the corresponding methods of the nested component.

The ComponentContainer separates the application and the nested component. The control tree and data binding of the inner component are decoupled from the outer component.

If you want to share data with the inner component, you can use the propagateModel property on the ComponentContainer to forward models and binding contexts to the inner component.

You load and create a UIComponent in one of the following ways:
  • Load the component asynchronously before creating the container:
    	var oComponentPromise = sap.ui.component({
    		name: "samples.components.sample",
    		async: true
    	});
    
    	var oContainer = new sap.ui.core.ComponentContainer({
    		component : oComponentPromise
    	});
    	oContainer.placeAt("target");
    
  • Load the component asynchronously while creating the container:
    	var oContainer = new sap.ui.core.ComponentContainer({
    		name: "samples.components.sample",
    		lifecycle: sap.ui.core.ComponentLifecycle.Container,
    		async: true
    	});
    	oContainer.placeAt("target");
    
  • Load the component asynchronously with "manifest first" mode by specifying the URL of the descriptor (manifest.json):
    	var oComponentPromise = sap.ui.component({
    		manifestUrl: "samples/components/sample/manifest.json",
    		async: true
    	});
    
    	var oContainer = new sap.ui.core.ComponentContainer({
    		component : oComponentPromise
    	});
    	oContainer.placeAt("target");
    
  • Load the component asynchronously with "manifest first" mode by specifying the component name:
    	var oComponentPromise = sap.ui.component({
    		name: "samples.components.sample",
    		manifestFirst: true,
    		async: true
     	});
    
    	var oContainer = new sap.ui.core.ComponentContainer({
    		component : oComponentPromise
    	});
    	oContainer.placeAt("target");

You can use the lifecycle property to determine whether the container or your application code will take care of destroying the component.

Reuse Components

To be able to reuse a component, the component has to be declared in the componentUsages section of the manifest.json descriptor file as follows:
"sap.ui5": {
  "componentUsages": {
    "myreuse": {
      "name": "sap.reuse.component",
      "settings": {},
      "componentData": {}
    }
  }
}

The reuse component is declared via its componentUsage ID as the key and the supported values are name (name of the component), settings, and componentData. The values defined in the manifest.json file will be merged with the values specified in the instance-specific component factory function. Allowed values in the instance-specific factory function are settings, componentData, async, and id.

For more information, see Descriptor for Applications, Components, and Libraries.

If you want to exchange the reuse component, for example, to extend an app, you simple exchange the reuse component in the manifest.json descriptor file.

The application index can also access the information in the manifest.json file and optimize the determination of dependencies when loading components.

Reuse components that are embedded by a library must have an explicit entry in the manifest.json in the sap.app/embeddedBy section:
"sap.app": {
  "embeddedBy": "../"
}
Under embeddedBy, you specify the relative path to the namespace root of the library. This ensures that tools like the application index can discover embedded libraries and won't include them in the transitive scope (otherwise you would get unwanted 404 requests). Additionally tools should declare a library dependency to the embedding library. This will ensure that the library containing the component preload will be loaded automatically instead of the trying to load the component preload by itself.

Instantiation

To instantiate the reuse component in the current component, you use an instance-specific factory function. The factory function requires at least the componentUsage ID as a parameter (simplified usage) or a configuration object that contains the usage and optionally settings and componentData (extended usage).

  • Example for simplified usage:
    var oComponentPromise = this.createComponent("myreuse");
  • Example for extended usage:
    var oComponentPromise = this.createComponent({
      usage: "myreuse"
      settings: {},
      componentData: {},
      async: true 
    });

Declarative Usage

You can also declare a reuse component directly, for example, in your JavaScript or XML code. In an XML view, the local service factory can only be used via the ComponentContainer that has a superordinate component.
<View ...>
  <ComponentContainer usage="myreuse" async="true"></ComponentContainer>
</View>

Migration

If you have been reusing components before we introduced the reuse feature described above, we recommend that you refactor your code and implement the new logic.

If you use a component that is embedded in a library, and the application declares a dependency to that library, remove the dependency to the library from the embedding application. Make sure that the application code does not contain any direct references to the component or the embedding application.

Old Code

Recommended Code

manifest.json with dependency declaration only:
{
  "sap.ui5": {
    "dependencies": {
      "components": {
        "sap.reuse.component": {}
      }
    }
  }
}
manifest.json with declaration of reuse components:
{
  "sap.ui5": {
    "dependencies": {
      "components": {
        "sap.reuse.component": {}
      }
    },
    "componentUsages": {
      "reuse": {
        "name": "sap.reuse.component"
      }
    }

  }
}
Component.js with nested reuse component:
createContent: function() {
   
  var oReuseComponent = sap.ui.component({
    "name": "sap.reuse.component"
  });
 
}
Component.js that loads the reuse component
createContent: function() {
   
  var oReuseComponentPromise = this.createComponent({ /* this = Component instance */
    "usage": "reuse"
  });
 
}