HarmonyOS 嵌套组件能否支持state传递或provider、consumer?

​Consulting description: 嵌套组件能否支持state传递或provider、consumer,这样封装组件会方便一点

例如:

Map.ets代码:​

import { map } from '@kit.MapKit';  
import { AsyncCallback } from '@kit.BasicServicesKit';  
  
import MapComponent from './MapContainer';  
  
@Entry  
@Component  
export default struct Map {  
  private callback?: AsyncCallback<map.MapComponentController>;  
  @Provide map?: map.MapComponentController = undefined;  
  
  aboutToAppear(): void {  
    this.callback = async (err, mapController) => {  
      if (!err) {  
        this.map = mapController;  
      }  
    }  
  }  
  
  build() {  
    Column() {  
      Stack() {  
        MapComponent({ callback: this.callback })  
      }  
    }.width('100%').height('100%')  
  }  
}  

MapMaker代码如下:

import { map, mapCommon } from '@kit.MapKit';  
  
@Component  
export default struct MapMarker {  
  // Marker初始化参数  
  options?: mapCommon.MarkerOptions;  
  @Consume map?: map.MapComponentController;  
  
  async aboutToAppear() {  
    await this.map?.addMarker(this.options);  
  }  
  
  build() {  
  
  }  
}

业务如下使用:

Map({...}){  
    MapMaker({...})  
}
HarmonyOS
2024-10-28 10:38:26
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zxjiu

​目前自定义组件内嵌套是支持的,需要使用@BuilderParam

您是想在父组件Map中初始化一次MapComponentController后,在后代组件能支持调用controller的方法,同时又不想通过一层层透传的方式传递controller。

在此场景下,开发者您所说的@Provide-@Consume方案是可行的,通过相同变量名或相同key的方式实现祖先组件和后代组件的成员双向绑定,详细使用文档可以参考:

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-provide-and-consume-V5

样例代码如下:​

import { mapCommon, MapComponent } from '@kit.MapKit';  
import { map } from '@kit.MapKit';  
import { AsyncCallback } from '@kit.BasicServicesKit';  
import GeoManagerViewModel from '../viewModel/GeoManagerViewModel';  
import { common } from '@kit.AbilityKit';  
import { geoLocationManager } from '@kit.LocationKit';  
  
@Component  
export struct Map {  
  private mapOption?: mapCommon.MapOptions;  
  private callback?: AsyncCallback<map.MapComponentController>;  
  // 相同变量名绑定  
  @Provide mapController?: map.MapComponentController = undefined;  
  
  aboutToAppear(): void {  
    // 地图初始化参数,设置地图中心点坐标及层级  
    this.mapOption = {  
      position: {  
        target: {  
          latitude: 39.9,  
          longitude: 116.4  
        },  
        zoom: 10  
      }  
    };  
  
    // 地图初始化的回调  
    this.callback = async (err, mapController) => {  
      if (!err) {  
        // 获取地图的控制器类,用来操作地图  
        this.mapController = mapController;  
        // 启用我的位置图层  
        this.mapController?.setMyLocationEnabled(true);  
        // 启用我的位置按钮  
        this.mapController?.setMyLocationControlsEnabled(true);  
      }  
    };  
  }  
  
  build() {  
    RelativeContainer() {  
      MapComponent({ mapOptions: this.mapOption, mapCallback: this.callback })  
        .width("100%")  
        .height("100%")  
        .id("map_component")  
  
      Maker()  
        .id("map_maker")  
  
      Proxy()  
        .alignRules({  
          bottom: {anchor: "__container__", align: VerticalAlign.Bottom}  
        })  
        .id("map_maker_2")  
    }  
    .width("100%")  
    .height("100%")  
  }  
}  
  
@Component  
export struct Proxy {  
  build() {  
    Maker()  
  }  
}  
  
@Component  
export struct Maker {  
  // 相同变量名绑定  
  @Consume mapController?: map.MapComponentController  
  private context = getContext(this) as common.UIAbilityContext  
  private location?: geoLocationManager.Location  
  
  aboutToAppear(): void {  
    GeoManagerViewModel.requestLocation(this.context)  
      .then((location: geoLocationManager.Location | undefined) => {  
        this.location = location  
      })  
  }  
  
  build() {  
    Button("center")  
      .width("100%")  
      .height(50)  
      .onClick(() => {  
        // 根据位置移动地图相机  
        let target: mapCommon.LatLng = {  
          latitude: this.location?.latitude ?? 0,  
          longitude: this.location?.longitude ?? 0  
        };  
        let cameraPosition: mapCommon.CameraPosition = {  
          target: target,  
          zoom: 10  
        };  
        let cameraUpdate: map.CameraUpdate = map.newCameraPosition(cameraPosition);  
        this.mapController?.animateCamera(cameraUpdate, 500)  
      })  
  }  
}
分享
微博
QQ
微信
回复
2024-10-28 15:07:40
相关问题
组件事件能否传递组件
2275浏览 • 1回复 待解决
ArkUI组件能否支持继承
1216浏览 • 1回复 待解决
能否嵌套定义 Record<string,Record>
1837浏览 • 1回复 待解决
HarmonyOS 组件嵌套问题
313浏览 • 1回复 待解决
HarmonyOS Tabs组件嵌套Tabs组件问题
601浏览 • 1回复 待解决
HarmonyOS 组件@State最小化build监听VM
173浏览 • 1回复 待解决
HarmonyOS Tabs组件嵌套滑动
229浏览 • 1回复 待解决
Tabs组件嵌套滑动组件
1313浏览 • 1回复 待解决
HarmonyOS Refresh组件嵌套滑动冲突问题
752浏览 • 1回复 待解决