docs

Controller Replacement

Controller replacement lets you completely substitute an existing controller with a custom implementation. This approach gives you full control over the controller logic.

Tip:

Before opting for controller replacement, consider whether Controller Extensions would meet your needs. Controller extensions offer better maintainability, support multiple layers of extensions, and are preferred for most scenarios.

To replace a controller without altering the view, simply configure it in the sap.ui.controllerReplacements section of your component’s manifest.json file:

{
    "sap.ui5": {
        "extends": {
            "extensions": {
                "sap.ui.controllerReplacements": {
                    "samples.components.ext.sap.Main": "samples.components.ext.customer.CustomMain"
                }
            }
        }
    }
}

Best Practices


When to Use Controller Replacement


Lifecycle Method Handling

Unlike in controller extensions, lifecycle method chaining is not automatic in controller replacement. You have full control over when and whether to call the parent lifecycle methods. The example below shows how to overwrite the onAfterRendering lifecycle method in your replacement controller:

// You have to determine the execution order manually when overwriting a lifecycle function
onAfterRendering() {
    // Custom logic first
    this.customLogic();

    // Then parent logic
    super.onAfterRendering();

    // Or additional logic after parent's lifecycle function
    this.finalizeCustomSetup();
}

Complete Replacement of Controllers

The following examples show how to completely replace a controller with a new sap.ui.core.Controller subclass.


JavaScript Implementation

For JavaScript-based controllers, you can extend the original controller using the extend syntax:

sap.ui.define([
    "sap/ui/core/mvc/Controller"
], (Controller) => {
    "use strict";

    return Controller.extend("samples.components.ext.customer.CustomMain", {
        onInit() { 
            // Custom initialization logic
        },
        onBeforeRendering() { 
            // Custom pre-rendering logic
        },
        onAfterRendering() {
            // Custom post-rendering logic
        },
        onExit() {
            // Custom cleanup logic
        },
        myEventHandler(oEvent) { 
            // Custom event handling
        }
    });
});

TypeScript Implementation

For TypeScript projects, use the ES6 class syntax, which provides better type safety and code completion:

import Controller from "sap/ui/core/mvc/Controller";

/**
 * @namespace samples.components.ext.customer
 */
export default class CustomMainController extends Controller {

    onInit(): void {
        // Custom initialization logic
    }

    onBeforeRendering(): void {
        // Custom pre-rendering logic
    }

    onAfterRendering(): void {
        // Custom post-rendering logic  
    }

    onExit(): void {
        // Custom cleanup logic
    }

    myEventHandler(evt: Event): void {
        // Custom event handling with proper typing
    }
}

Subclassing Existing Controllers via Replacement

Instead of replacing a controller with a fresh sap.ui.core.Controller subclass, you can also extend the existing controller to preserve its original functionality.


JavaScript Implementation

sap.ui.define([
    "samples/components/ext/sap/Main.controller"
], (MainController) => {
    "use strict";

    return MainController.extend("samples.components.ext.customer.CustomMain", {
        onInit() { 
            // Call parent method using super
            super.onInit();
            // Add custom logic
        },
        onBeforeRendering() { 
            super.onBeforeRendering();
            // Add custom logic
        },
        onAfterRendering() {
            // Add custom logic first
            super.onAfterRendering();
        },
        onExit() {
            // Add custom cleanup
            super.onExit();
        },
        myEventHandler(oEvent) {
            super.myEventHandler(oEvent);
            // Add custom logic 
        }
    });
});

TypeScript Implementation

import MainController from "samples/components/ext/sap/Main.controller";

/**
 * @namespace samples.components.ext.customer
 */
export default class CustomMainController extends MainController {

    onInit(): void {
        super.onInit();
        // Add your custom initialization logic
    }

    onBeforeRendering(): void {
        super.onBeforeRendering();
        // Add your custom pre-rendering logic
    }

    onAfterRendering(): void {
        // Execute custom logic first, then parent
        super.onAfterRendering();
    }

    onExit(): void {
        // Custom cleanup
        super.onExit();
    }

    myEventHandler(evt: Event): void {
        super.myEventHandler(evt);
        // Add your custom event handling
    }
}

Note:

Modern OpenUI5 supports the super keyword for accessing parent methods, which is cleaner and more readable than the native JavaScript prototype.apply() call. The super keyword is available in both JavaScript (ES6+) and TypeScript implementations.

Related Information

Controller Extensions

Configuration in the manifest.json

View Replacement

TypeScript Support