HarmonyOS Next Best Practices for Actively Invoking Methods Encapsulated in Custom Controls
1. Background Introduction
The primary development language for HarmonyOS Next is ArkTS, and its framework ArkUI is a declarative UI. Declarative UIs typically do not manipulate controls directly but drive UI refreshes through state variable updates. However, in some scenarios, state-driven UI refreshes cannot meet complex business logic, requiring parent layouts to invoke methods in child controls. How to handle this?
2. Reference to System Approaches
System-provided controls like Dialog, TextTimer, and TextArea require a controller during construction, allowing parent controls to directly invoke child control methods via the controller:
- 
TextTimerControllerprovidesstart,pause, andresetmethods for parent components.
- 
CustomDialogControllerprovidesopenandclosemethods for parent components.
We can adopt a similar approach: encapsulate a controller for child components to enable parent-component invocation.
3. Encapsulation of Child Component Invocation
The parent component invokes methods of the child component by calling a controller exposed by the child component. This encapsulates capabilities like data processing, refreshing, animations, and notifications.
Implementation Steps:
- Define a ChildControllerclass with methods matching those in the child component:
class ChildController { 
  changeText = (value: string) => { console.log('11111') } 
} 
export let ChildRef = new ChildController()
- In the child component, assign actual methods to the controller. In aboutToAppear, map the child component's methods to the controller's method variables:
@Component
struct Child {
  @State private text: string = '初始值';
  private controller: ChildController = new ChildController();
  aboutToAppear() {
    if (this.controller) {
      this.controller.changeText = this.changeText;
    }
    console.log('aaa');
  }
  private changeText = (value: string) => {
    this.text = value;
    console.log('bbb');
  }
  build() {
    Column() {
      Text(this.text);
    }
  }
}
- In the parent component, create a controller object, pass it to the child component, and invoke the controller's methods:
@Entry
@Component
struct Parent {
  private ChildRef = new ChildController();
  build() {
    Column() {
      Text('调用 Child 的 changeText').fontSize('18vp').fontColor(Color.Gray);
      Divider();
      Child({ controller: this.ChildRef });
    }
  }
}
4. Design Analysis
This approach uses an intermediate controller object for indirect communication:
- The parent component holds the controller, while the child component assigns its actual methods to the controller during initialization.
- When the parent component invokes the controller's methods, it effectively calls the child component's methods.
- This achieves loose coupling, avoiding direct parent dependency on child component internals, and enhances code maintainability and extensibility.
5. Summary
This article introduces a method for parent components to invoke child components in the declarative UI framework ArkUI. Through loose-coupling communication, it solves the challenge of parent components directly invoking child component methods without holding direct references.
 
 
              
 
    
Top comments (0)