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:
-
TextTimerController
providesstart
,pause
, andreset
methods for parent components. -
CustomDialogController
providesopen
andclose
methods 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
ChildController
class 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)