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%')  
  }  
}  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.

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() {  
  
  }  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

业务如下使用:

Map({...}){  
    MapMaker({...})  
}
  • 1.
  • 2.
  • 3.
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)  
      })  
  }  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
分享
微博
QQ
微信
回复
2024-10-28 15:07:40
相关问题
组件事件能否传递组件
3078浏览 • 1回复 待解决
ArkUI组件能否支持继承
2381浏览 • 1回复 待解决
能否嵌套定义 Record<string,Record>
2311浏览 • 1回复 待解决
HarmonyOS @State支持HashMap吗
725浏览 • 1回复 待解决
HarmonyOS 能否通过eventHub传递Want数据
579浏览 • 1回复 待解决