【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区三级联动地址选择器组件(下)

news2024/12/23 6:30:13

文章目录

  • 概述
  • 端云调用流程
  • 端侧集成AGC SDK
  • 端侧省市地区联动的地址选择器组件开发
    • 创建省市数据模型
    • 创建省市地区视图UI子组件
    • 创建页面UI视图Page文件
  • 打包测试
  • 总结

概述

我们在前面的课程,对云开发的入门做了介绍,以及使用一个省市地区联动的地址选择器示例,为大家演示了如何创建云开发工程,以及云数据库、云函数的开发实战。如果有读者还没看过前面的这两篇文章,那在读这篇文章之前,建议先看下以下这两篇文章,之后再来阅读本篇文章,会更好理解云开发这块的内容。
《【鸿蒙应用ArkTS开发系列】- 云开发入门简介》
《【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区三级联动地址选择器组件(上)》

那我们现在正式开始今天的课程,本次课程是 《【鸿蒙应用ArkTS开发系列】- 云开发入门实战二 实现省市地区三级联动地址选择器组件(上)》 的下篇,上篇我们完成了省市地区联动的地址选择器云工程的云数据、云函数的开发跟部署,这次的课程,我们将开发一个鸿蒙客户端,来调用云服务的API,获取地址信息数据进行展示。

通过本次课程,我们将学习到以下内容:

  1. 鸿蒙客户端如何集成AGC SDK;
  2. 鸿蒙客户端如何调用云函数获取数据;
  3. 实现省市地区联动的地址选择器组件;
  4. ArkUI @Provide、@Consume、@Watch等状态管理装饰器的使用

那下面我们直接进入本次课程的学习。按照惯例,这里先上成品效果图:

在这里插入图片描述
上面由于是用的云端地址位置数据,因此会有一个加载的过程,实际开发时,我们也可以将地址数据内置到客户端中,或者网络数据做一个缓存处理,这样用户体验会更好一些。

端云调用流程

下面我们先看下客户端跟云服务之间的一个交互流程图:
在这里插入图片描述

端侧集成AGC SDK

客户端工程应该怎么集成AGC SDK呢,这一步,我建议还是跟《【鸿蒙应用ArkTS开发系列】- 云开发入门简介》 中提到的,使用端云一体化开发目标来创建工程,这样 DevEco Studio会为端侧工程自动集成AGC相关云服务最新版本SDK。

  1. “entry/src/main/resources/rawfile/agconnect-services.json”:AGC
    SDK配置文件,内含client_secret和api_key,请妥善保管。
    在这里插入图片描述
  2. “entry/oh-package.json5”:自动引入了AGC相关云服务(认证服务、云函数、云存储)最新版本SDK,同时会自动集成端云一体化登录组件的最新SDK。
    工程同步成功后可以看到当前从ohpm仓获取的最新版本。
    在这里插入图片描述
    上图是之前创建的,现在的版本的已经有所更新,大家根据IDE实际创建的版本来。我目前工程集成的SDK是下面这样的
    在这里插入图片描述
    如果是已经存在的端侧工程,那需要按照官网的AGC SDK 集成方式集成,包括从AppGallery-Connect 中下载项目agconnect-services.json文件导入到端侧工程,以及对应的AGC SDK库进行 ohpm依赖安装。
    在这里插入图片描述官网 HarmonyOS使用入门(ArkTS API9及以上) 对鸿蒙集成AGC服务 讲解的很详细,这里就不过多赘述,大家直接看官方文档即可。

做完前期工作,那我们开始进入本篇课程的重点内容,开发一个省市地区联动的地址选择器组件。

端侧省市地区联动的地址选择器组件开发

创建省市数据模型

打开DevEco Studio,在"Application-> entry -> src -> main -> ets 下创建一个bean目录,用于存放省市数据的数据模型类,在目录中创建ProvinceBean(省)、CityBean(市)、DistrictBean(区县),

在这里插入图片描述

完成代码如下:

ProvinceBean.ts

/**
 * 省份信息
 */
export class ProvinceBean {
  public id: number;
  public code: string;
  public label: string;
}

CityBean.ts

/**
 * 城市信息
 */
export class CityBean {
  public id: number;
  public province_code: string;
  public code: string;
  public label: string;
}

DistrictBean.ts

/**
 * 区县信息
 */
export class DistrictBean {
  public id: number;
  public city_code: string;
  public code: string;
  public label: string;
}

创建省市地区视图UI子组件

打开DevEco Studio,在"Application-> entry -> src -> main -> ets "目录下新建一个"component"文件夹来存放省份UI子组件、城市UI子组件、区县UI子组件。
在这里插入图片描述
在component目录上右键,点击New ->ArkTS File 菜单, 创建三个UI子组件(ProvinceComponent、CityComponent、DistrictComponent)
在这里插入图片描述
完整代码如下:

ProvinceComponent.ets

import agconnect from '@hw-agconnect/api-ohos';
import "@hw-agconnect/function-ohos";

import { ProvinceBean } from '../bean/ProvinceBean'
import { Log } from '../common/Log';

@Component
export struct ProvinceComponent {
  @State mProvinceData: ProvinceBean[] = [];
  @Consume currentProvince: ProvinceBean;

  aboutToAppear() {
    this.callFunction();
  }

  build() {
    Row() {
      Column() {
        Text('省份')
          .width('100%')
          .height(50)
          .fontSize(20)
          .fontWeight(500)
          .textAlign(TextAlign.Center)
          .border({
            color: '#e2e2e2',
            width: { bottom: 1 }
          })

        if (this.mProvinceData.length === 0) {

          Text('加载中').fontSize(20).height('100%').layoutWeight(1)

        } else {
          List({ space: 10, initialIndex: 0 }) {
            ForEach(this.mProvinceData, (item: ProvinceBean) => {
              ListItem() {
                Text(item.label)
                  .width('100%')
                  .height(50)
                  .fontSize(20)
                  .textAlign(TextAlign.Center)
              }
              .backgroundColor(this.currentProvince?.code === item.code ? '#c8aaf4fc' : Color.Transparent)
              .onClick(() => {
                this.currentProvince = item;
              })
            }, item => JSON.stringify(item))
          }
          .width('100%')
          .height('100%')
          .divider({ strokeWidth: 1, color: "#e2e2e2", startMargin: 5, endMargin: 5 })
        }
      }
      .backgroundColor(Color.White)
      .border({
        color: '#e2e2e2',
        width: { right: 0.5 }
      })
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }

  callFunction() {
    agconnect.instance().init(getContext(this));
    let functionCallable = agconnect.function().wrap("province-query-$latest");
    let params = {};
    functionCallable.call(params).then((ret: any) => {
      Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));
      this.mProvinceData = ret.getValue().result;
      if (this.mProvinceData.length > 0) {
        this.currentProvince = this.mProvinceData[0];
      }
    }).catch((error: any) => {
      Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));
    });
  }
}


CityComponent.ets

import agconnect from '@hw-agconnect/api-ohos';
import { CityBean } from '../bean/CityBean';
import { ProvinceBean } from '../bean/ProvinceBean';
import { Log } from '../common/Log';

@Component
export struct CityComponent {
  @State mTip: string = ''
  @State mCityData: CityBean[] = [];
  @Consume @Watch('onProvinceChange') currentProvince: ProvinceBean;
  @Consume currentCity: CityBean;

  build() {
    Row() {
      Column() {

        Text('城市')
          .width('100%')
          .height(50)
          .fontSize(20)
          .fontWeight(500)
          .textAlign(TextAlign.Center)
          .border({
            color: '#e2e2e2',
            width: { bottom: 1 }
          })

        if (this.mCityData.length === 0) {

          Text(this.mTip).fontSize(20).height('100%').layoutWeight(1)

        } else {

          List({ space: 10, initialIndex: 0 }) {
            ForEach(this.mCityData, (item: CityBean) => {
              ListItem() {
                Text(item.label)
                  .width('100%')
                  .height(50)
                  .fontSize(20)
                  .textAlign(TextAlign.Center)
              }
              .backgroundColor(this.currentCity?.code === item.code ? '#c8aaf4fc' : Color.Transparent)
              .onClick(() => {
                this.currentCity = item;
              })
            }, item => JSON.stringify(item))
          }
          .width('100%')
          .height('100%')
          .divider({ strokeWidth: 1, color: "#e2e2e2", startMargin: 5, endMargin: 5 })
        }
      }
      .backgroundColor(Color.White)
      .border({
        color: '#e2e2e2',
        width: { right: 0.5 }
      })
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }

  onProvinceChange() {
    Log.info("Functions", "onProvinceChange");
    this.mCityData.splice(0, this.mCityData.length);
    if (this.currentProvince) {
      this.mTip = '加载中';
      this.callFunction(this.currentProvince.code);
    }
  }

  callFunction(provinceCode: string) {
    agconnect.instance().init(getContext(this));
    let functionCallable = agconnect.function().wrap("city-query-$latest");
    let params = { "code": provinceCode };
    Log.info("Functions", "Cloud Function Called, body: " + JSON.stringify(params));
    functionCallable.call(params).then((ret: any) => {
      Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));
      this.mCityData = ret.getValue().result;
      if (this.mCityData.length > 0) {
        this.currentCity = this.mCityData[0];
      }
    }).catch((error: any) => {
      Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));
    });
  }
}


DistrictComponent.ets

import agconnect from '@hw-agconnect/api-ohos';
import { CityBean } from '../bean/CityBean';
import { DistrictBean } from '../bean/DistrictBean';
import { Log } from '../common/Log';
import { ProvinceBean } from '../bean/ProvinceBean';

@Component
export struct DistrictComponent {

  @State mTip: string = ''
  @State mDistrictData: DistrictBean[] = [];
  @Consume @Watch('onProvinceChange') currentProvince: ProvinceBean;
  @Consume @Watch('onCityChange') currentCity: CityBean;
  @Consume currentDistrict: DistrictBean;


  build() {
    Row() {
      Column() {

        Text('区县')
          .width('100%')
          .height(50)
          .fontSize(20)
          .fontWeight(500)
          .textAlign(TextAlign.Center)
          .border({
            color: '#e2e2e2',
            width: { bottom: 1 }
          })

        if (this.mDistrictData.length === 0) {

          Text(this.mTip).fontSize(20).height('100%').layoutWeight(1)

        } else {

          List({ space: 10, initialIndex: 0 }) {
            ForEach(this.mDistrictData, (item: DistrictBean) => {
              ListItem() {
                Text(item.label)
                  .width('100%')
                  .height(50)
                  .fontSize(20)
                  .textAlign(TextAlign.Center)
              }
              .backgroundColor(this.currentDistrict?.code === item.code ? '#c8aaf4fc' : Color.Transparent)
              .onClick(() => {
                this.currentDistrict = item;
              })
            }, item => JSON.stringify(item))
          }
          .width('100%')
          .height('100%')
          .divider({ strokeWidth: 1, color: "#e2e2e2", startMargin: 5, endMargin: 5 })
        }
      }
      .backgroundColor(Color.White)
      .border({
        color: '#e2e2e2',
        width: { right: 0.5 }
      })
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Center)
    }
    .height('100%')
  }

  onProvinceChange() {
    this.mDistrictData.splice(0, this.mDistrictData.length);
  }

  onCityChange() {
    Log.info("Functions", "onCityChange");
    this.mDistrictData.splice(0, this.mDistrictData.length);
    if (this.currentCity) {
      this.mTip = '加载中';
      this.callFunction(this.currentCity.code);
    }
  }

  callFunction(cityCode: string) {
    agconnect.instance().init(getContext(this));
    let functionCallable = agconnect.function().wrap("districts-query-$latest");
    let params = { "code": cityCode };
    Log.info("Functions", "Cloud Function Called, body: " + JSON.stringify(params));
    functionCallable.call(params).then((ret: any) => {
      Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));
      this.mDistrictData = ret.getValue().result;
      if (this.mDistrictData.length > 0) {
        this.currentDistrict = this.mDistrictData[0];
      }
    }).catch((error: any) => {
      Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));
    });
  }

}

三个UI子组件的UI样式基本一致,功能也是基本一致,大家也可以进行代码封装重构,基于通用模型抽取成一个模板组件,这里只演示功能,就不过多赘述。在这里我们就拿城市列表视图 CityComponent.ets来进行代码的讲解。

1、首先我们定义了四个状态变量。

  @State mTip: string = ''
  @State mCityData: CityBean[] = [];
  @Consume @Watch('onProvinceChange') currentProvince: ProvinceBean;
  @Consume currentCity: CityBean;
  • mTip 用于显示加载中提示语
  • mCityData 是城市列表的数据源
  • currentProvince 是当前选中的省份信息对象(我们基于该对象的省份编码来查询城市列表)。
  • currentCity 是记录当前选中的城市。

这里currentProvince 、currentCity 使用**@Consume装饰**,用于跟页面中 @Provide装饰 的状态变量(currentProvince 、currentCity)做双向状态同步,这样Page页面可以拿到当前选中的省份、选中的城市的数据,其他的子组件之间也可以进行数据共享。

currentProvince 同时还用了 @Watch(‘onProvinceChange’)装饰,因为城市列表视图 CityComponent需要实时监听切换省份的事件,来动态调用云函数接口获取对应省份的城市数据,因此这里使用@Watch对currentProvince数据进行观察,如果省份视图子组件中选中的省份有所改变,onProvinceChange方法将会接收到回调。

2、build 方法

UI视图绘制这里,我们根据城市数据源的数据情况,如果是没数据,就显示mTip ,如果mCityData 有数据,就使用一个列表进行数据展示

2、onProvinceChange方法

onProvinceChange() {
    Log.info("Functions", "onProvinceChange");
    this.mCityData.splice(0, this.mCityData.length);
    if (this.currentProvince) {
      this.mTip = '加载中';
      this.callFunction(this.currentProvince.code);
    }
  }

当选中的省份数据有变动时,onProvinceChange会被触发,我们在该方法中将mCityData 数据源清空,给mTip 设置一个等待提示语,然后调用callFunction 方法请求云函数根据省份编码查询城市列表数据。因为currentProvince 是跟Page页面和省份子组件是进行数据双向同步的,因此onProvinceChange触发的时候this.currentProvince.code 也是能拿到最新的切换后的省份编码。

3、callFunction方法
这里我们重点讲下这个方法,这关系到云函数的调用。

 callFunction(provinceCode: string) {
    agconnect.instance().init(getContext(this));
    let functionCallable = agconnect.function().wrap("city-query-$latest");
    let params = { "code": provinceCode };
    Log.info("Functions", "Cloud Function Called, body: " + JSON.stringify(params));
    functionCallable.call(params).then((ret: any) => {
      Log.info("Functions", "Cloud Function Called, Returned Value: " + JSON.stringify(ret.getValue()));
      this.mCityData = ret.getValue().result;
      if (this.mCityData.length > 0) {
        this.currentCity = this.mCityData[0];
      }
    }).catch((error: any) => {
      Log.error("Functions", "Error - could not obtain cloud function result. Error Detail: " + JSON.stringify(error));
    });
  }
  • 拿到agconnect实例并进行初始化
  • 通过 agconnect.function().wrap(“city-query-$latest”) 拿到云函数对象控制器,这里具体要调用哪一个云函数,在wrap方法中采用“云函数名称-版本号” 定义,latest 是最新版本。
  • 使用functionCallable.call(params)触发请求,params是body,数据类型是JSON对象
  • 使用then异步获取返回的数据,通过ret.getValue()获取数据
  • 使用catch处理异常错误情况

三个UI视图子组件开发完毕,下面我们创建个Page页面将三个子组件整合起来显示。

创建页面UI视图Page文件

1、打开DevEco Studio,在"Application-> entry -> src -> main -> ets -> pages"目录下新建一个"AreaPage.ets"文件来实现省市地区联动地址选择器功能的页面。
在这里插入图片描述
2、配置页面路由
由于模板已经创建了一个main_pages.json文件进行统一的页面管理,所以我们需要将新建的页面注册在"Application-> entry -> src -> main -> resources -> base ->profile -> main_pages.json"文件中。
3、 在EntryAbility.ts 类中onWindowStageCreate 方法中, 将

windowStage.loadContent('pages/Index', (err, data) => {}

中的第一个参数,修改为’pages/AreaPage’

windowStage.loadContent('pages/AreaPage', (err, data) => {}

4、在AreaPage界面放三个控件:一个省份视图子组件显示省份列表,一个城市视图子组件显示城市列表,并与选择的省份进行数据联动,一个区县视图子组件显示区县列表,并与选择的城市进行数据联动,完整示例代码如下。

import { CityBean } from '../bean/CityBean'
import { DistrictBean } from '../bean/DistrictBean'
import { ProvinceBean } from '../bean/ProvinceBean'
import { CityComponent } from '../component/CityComponent'
import { DistrictComponent } from '../component/DistrictComponent'
import { ProvinceComponent } from '../component/ProvinceComponent'

@Entry
@Component
export struct AreaPage {
  @Provide currentProvince: ProvinceBean = null;
  @Provide currentCity: CityBean = null;
  @Provide currentDistrict: DistrictBean = null;

  build() {
    Row() {
      ProvinceComponent().width('30%')
      CityComponent().width('35%')
      DistrictComponent().width('35%')
    }
    .height('100%')
  }
}

这里我们定义了三个状态变量,存储当前选择的省份、选择的城市、选择的区县这三个对象,并使用@Provide装饰器,这样@Provide装饰的状态变量与子组件的@Consume装饰器装饰的同名状态变量,会实现一个数据状态双向绑定。具体如下图:

AreaPage-currentProvince分别与ProvinceComponent-currentProvince 、 CityComponent-currentProvince 直接建立数据状态双向绑定,ProvinceComponent-currentProvince 与CityComponent-currentProvince 间接建立数据状态双向绑定。
在这里插入图片描述
这样,我们这个省市区县联动的地址选择器功能就完成了。

打包测试

1.DevEco Studio菜单选择“File -> Project Structure”,在“Project Structure”界面导航选择“Project”,选择“Signing Configs”页签。

2.勾选“Automatically generate signature” ,自动签名完成后点击“OK”。
在这里插入图片描述
3.将应用服务推送到支持API 9及以上版本的手机。

4.显示效果如下:
在这里插入图片描述
5.控制台日志如下:
在这里插入图片描述

总结

通过《【鸿蒙应用ArkTS开发系列】- 云开发入门实战三 实现省市地区三级联动地址选择器组件》上下篇这两篇文章, 你应该已经成功地掌握使用HarmonyOS云开发能力开发了一个应用,学会如何使用云数据库、云函数,实现端、云的交互。

感谢阅读,后续有疑问或者其他问题,可以在评论区留言交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1245935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDM(Internet Download Manager)PC版提升下载速度与效率的利器

你是否曾经因为下载速度慢而感到烦恼?或者在下载大型文件时,经历了长时间的等待?如果你有这样的困扰,那么IDM(Internet Download Manager)就是你的救星! IDM是一款高效、实用的下载管理器&…

PS 计数工具 基础使用方式讲解

上文PS 注释工具 基础使用方法讲解 中 我们讲了注释工具 解析来 我们来看这个计数工具 这里 我们换一张图像 如果 我要你数清楚 这个图上有几个咖啡豆 你能数清楚吗? 哈哈 其实也不难 不是特别大 但是 例如很多 且无规则物品时 我们可能就会数乱 左上角属性的话 我…

vue2【组件的构成】

目录 1:什么是组件化开发 2:vue中的组件化开发 3:vue组件的三个组成部分 4:组件中定义方法,监听器,过滤器,计算属性节点。 5:template中只允许唯一根节点,style默认…

arp报文及使用go实现

一、ARP协议报文格式及ARP表 ARP(Address Resolution Protocal,地址解析协议)是将IP地址解析为以太网的MAC地址(或者称为物理地址)的协议。在局域网中,当主机或其他网络设备有数据要发送给另一个主机或设备…

【2023年APMCM亚太杯C题】完整数据与解题思路

2023年亚太杯C题 数据下载与搜集重点数据其余数据第一问第二问第三问第四问第五问第六问 数据与思路获取 数据下载与搜集 该题并没有提供数据集,对所需数据进行收集整理是对题目进行求解的基础。在本题中,主要需要以下数据:新能源汽车历史销…

(免费领源码)java#springboot#mysql流浪动物救助系统78174-计算机毕业设计项目选题推荐

摘 要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存…

知行之桥EDI系统HTTP签名验证

本文简要概述如何在知行之桥EDI系统中使用 HTTP 签名身份验证,并将使用 CyberSource 作为该集成的示例。 API 概述 首字母缩略词 API 代表“应用程序编程接口”。这听起来可能很复杂,但真正归结为 API 是一种允许两个不同实体相互通信的软件。自开发以…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《基于外部性理论的网侧储能成本疏导机制研究》

这个标题涉及到一个关于储能的研究,主要聚焦在基于外部性理论的网侧(电网侧)储能成本疏导机制上。 基于外部性理论: 这表明研究的框架或者理论基础是"外部性理论"。外部性是指某个经济活动的影响不仅限于直接参与者&…

Adobe的组织工具程序Bridge 2024 版本下载与安装

目录 前言一、Bridge 2024安装二、使用配置总结 前言 Adobe Bridge是由 Adobe 公司开发的一款用于管理和组织创意资产的工具。它是Adobe Creative Cloud 套件的一部分,为设计师、摄影师和其他创意专业人员提供了一个集中管理和浏览其多媒体文件的平台。注&#xff…

JVM类加载的过程和JVM垃圾回收机制

文章目录 一、JVM类加载的过程1.1类加载的基本流程1.1.1加载1.1.2验证1.1.3准备1.1.4解析1.1.5初始化 1.2双亲委派模型 二、JVM垃圾回收机制2.1找到垃圾2.1.1引用计数(比如Python,PHP中用到)2.1.2可达性分析(比如Java中用到) 2.2释放垃圾2.2.1标记清除2.2.2复制算法…

小程序中的大道理--综述

前言 以下将用一个小程序来探讨一些大道理, 这些大道理包括可扩展性, 抽象与封装, 可维护性, 健壮性, 团队合作, 工具的利用, 可测试性, 自顶向下, 分而治之, 分层, 可读性, 模块化, 松耦合, MVC, 领域模型, 甚至对称性, 香农的信息论等等. 为什么不用大程序来说大道理呢? …

python写文件

output_file open(E:/XD_transfer/代码/CNN_new/try.csv, w) output_file.write(Sample, \n) for j in range(5):output_file.write(str(j) \n)

1-docker安装和配置、虚拟化、配置国内源、镜像操作、容器基本操作(run运行容器、-v目录映射、-p端口映射、容器其他操作)

1 docker和虚拟化 2 docker安装和配置 2.0 docker 中的一些概念 2.1 配置镜像加速器(国内源) 3 镜像操作 4 容器操作 4.1 容器基本操作 4.2 run运行容器 4.3 -v目录映射 4.4 -p端口映射 4.5 容器其他操作 1 docker和虚拟化 ## 什么是虚拟化在计算机中&…

数十亿美元商机!英国数字基础设施公司Equinix与法国量子计算公司Alice Bob 合作

​(图片来源:网络) 近日,全球数字基础设施公司Equinix宣布与全球领先的法国量子计算公司Alice & Bob合作,旨在共同开发市场上最为可靠的量子处理器之一。此次合作将使Equinix公司的客户通过使用Equinix Metal和Eq…

StarRocks Evolution:One Data,All Analytics

在 11 月 17 日举行的 StarRocks Summit 2023上,StarRocks TSC Member、镜舟科技 CTO 张友东详细介绍了 StarRocks 社区的发展情况,并全面解析了 StarRocks 的核心技术与未来规划;我们特意将他的精彩演讲整理出来,以帮助大家更深入…

合封芯片未来趋势如何?合封优势能否体现?

芯片已经成为现代电子设备的核心组件。为了提高系统的性能、稳定性和功耗效率,一种先进的芯片封装技术——合封芯片应运而生。 合封芯片作为一种先进的芯片封装技术,合封芯片是一种将多个芯片(多样选择)或不同的功能的电子元器件…

DevExpress中文教程 - 如何在macOS和Linux (CTP)上创建、修改报表(下)

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表。 DevExpress Reports — 跨平台报表组件&#x…

java 手机商城免费搭建+电商源码+小程序+三级分销+SAAS云平台

【SAAS云平台】打造全行业全渠道全场景的SaaS产品,为店铺经营场景提供一体化解决方案;门店经营区域化、网店经营一体化,本地化、全方位、一站式服务,为多门店提供统一运营解决方案;提供丰富多样的营销玩法覆盖所有经营…

[kingbase锁等待问题分析]

参考文章:https://www.modb.pro/db/70021 概述 为了确保复杂的事务可以安全地同时运行,kingbase(PostgreSQL)提供了各种级别的锁来控制对各种数据对象的并发访问,使得对数据库关键部分的更改序列化。事务并发运行,直到…

Vatee万腾的科技冒险:vatee创新力量的前沿发现

在当今飞速发展的科技潮流中,Vatee万腾以其独特的创新力量成为前沿的引领者。这场科技冒险不仅仅是技术的迭代,更是一次前所未有的前沿发现之旅,让我们一同深入探索Vatee万腾的科技冒险,感受vatee创新力量的前沿奇迹。 Vatee万腾将…